/// <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));
            }
        }