/// <summary> /// Преобразовать значение. /// </summary> /// <param name="value">Значение для преобразования.</param> /// <param name="toType">Тип, в который надо преобразовать.</param> /// <returns>Преобразованное значение.</returns> public static object Convert(object value, Type toType) { lock (TypeToTypeMethods) { Type fromType = value.GetType(); if (fromType == toType) { return(value); } if (fromType == typeof(string) && toType.IsEnum) { return(EnumCaption.GetValueFor((string)value, toType)); } if (fromType.IsEnum && toType == typeof(string)) { return(EnumCaption.GetCaptionFor(value)); } if (fromType == typeof(int) && toType.IsEnum) { return(Enum.Parse(toType, Enum.GetName(toType, value))); } if (fromType.IsEnum && toType == typeof(int)) { return((int)value); } TypeTypePair key = new TypeTypePair(fromType, toType); if (!ParsedTypes.Contains(fromType)) { AddTypeOperator(fromType); } if (!ParsedTypes.Contains(toType)) { AddTypeOperator(toType); } if (TypeToTypeMethods.ContainsKey(key)) { MethodInfo mi = TypeToTypeMethods[key]; return(mi.Invoke(null, new[] { value })); } if (toType == typeof(string)) { return(value.ToString()); } return(System.Convert.ChangeType(value, toType)); } }
/// <summary> /// Добавить тип и все его преобразования в кеш. /// </summary> /// <param name="type">Тип для добавления.</param> private static void AddTypeOperator(Type type) { ParsedTypes.Add(type); MethodInfo[] mis = type.GetMethods(); foreach (MethodInfo curmi in mis) { if (((curmi.IsSpecialName && (curmi.Name == "op_Implicit" || curmi.Name == "op_Explicit")) || curmi.Name == "Parse") && curmi.GetParameters().Length == 1) { TypeTypePair key = new TypeTypePair(curmi.GetParameters()[0].ParameterType, curmi.ReturnType); if (!TypeToTypeMethods.ContainsKey(key)) { TypeToTypeMethods.Add(key, curmi); } } } }
/// <summary> /// Можно ли преобразовать один тип к другому. /// </summary> /// <param name="fromType">Откуда будем преобразовывать.</param> /// <param name="toType">Куда будем преобразовывать.</param> /// <returns>Если можно преобразовать, то <c>true</c>.</returns> public static bool CanConvert(Type fromType, Type toType) { lock (TypeToTypeMethods) { if ((fromType == typeof(string) && toType.IsEnum) || (toType == typeof(string) && fromType.IsEnum)) { return(true); } if ((fromType == typeof(int) && toType.IsEnum) || (toType == typeof(int) && fromType.IsEnum)) { return(true); } TypeTypePair key = new TypeTypePair(fromType, toType); if (TypeToTypeMethods.ContainsKey(key)) { return(true); } if (!ParsedTypes.Contains(fromType)) { AddTypeOperator(fromType); } if (!ParsedTypes.Contains(toType)) { AddTypeOperator(toType); } return(TypeToTypeMethods.ContainsKey(key)); } }