Esempio n. 1
0
        /// <summary>
        /// 确定当前的 <see cref="System.Type"/> 的实例是否可以从指定 <see cref="System.Type"/>
        /// 的实例进行隐式类型转换。
        /// </summary>
        /// <param name="type">要判断的实例。</param>
        /// <param name="fromType">要与当前类型进行比较的类型。</param>
        /// <returns>如果当前 <see cref="System.Type"/> 可以从 <paramref name="fromType"/>
        /// 的实例分配或进行隐式类型转换,则为 <c>true</c>;否则为 <c>false</c>。</returns>
        /// <remarks>
        /// 判断类型间能否进行隐式类型转换的算法来自于 《CSharp Language Specification》v5.0
        /// 的第 6.1 节,更多信息可以参考我的博客文章
        /// <see href="http://www.cnblogs.com/JFToolKit/archive/p/TypeAssignableFrom.html">
        /// 《C# 判断类型间能否隐式或强制类型转换,以及开放泛型类型转换》</see>。</remarks>
        /// <example>
        /// 下面是 <see cref="IsImplicitFrom"/> 方法与 <see cref="System.Type.IsAssignableFrom"/> 方法的一些对比。
        /// <code>
        /// Console.WriteLine(typeof(object).IsAssignableFrom(typeof(uint))); // True
        /// Console.WriteLine(typeof(object).IsImplicitFrom(typeof(uint))); // True
        /// Console.WriteLine(typeof(int).IsAssignableFrom(typeof(short))); // False
        /// Console.WriteLine(typeof(int).IsImplicitFrom(typeof(short))); // True
        /// Console.WriteLine(typeof(long?).IsAssignableFrom(typeof(int?))); // False
        /// Console.WriteLine(typeof(long?).IsImplicitFrom(typeof(int?))); // True
        /// Console.WriteLine(typeof(long).IsAssignableFrom(typeof(TestClass))); // False
        /// Console.WriteLine(typeof(long).IsImplicitFrom(typeof(TestClass))); // True
        /// class TestClass {
        ///     public static implicit operator int(TestClass t) { return 1; }
        /// }
        /// </code>
        /// </example>
        /// <seealso href="http://www.cnblogs.com/JFToolKit/archive/p/TypeAssignableFrom.html">
        /// 《C# 判断类型间能否隐式或强制类型转换,以及开放泛型类型转换》</seealso>
        public static bool IsImplicitFrom(this Type type, Type fromType)
        {
            if (type == null || fromType == null)
            {
                return(false);
            }
            // 标识转换。
            if (type == fromType)
            {
                return(true);
            }
            // 对引用类型的支持。
            if (type.IsByRef)
            {
                type = type.GetElementType();
            }
            if (fromType.IsByRef)
            {
                fromType = type.GetElementType();
            }
            // 总是可以隐式类型转换为 Object。
            if (type.Equals(typeof(object)))
            {
                return(true);
            }
            // 判断是否可以进行标准隐式转换。
            if (IsStandardImplicitFrom(type, fromType))
            {
                return(true);
            }
            // 对隐式类型转换运算符进行判断。
            // 处理提升转换运算符。
            Type nonNullalbeType, nonNullableFromType;

            if (IsNullableType(type, out nonNullalbeType) &&
                IsNullableType(fromType, out nonNullableFromType))
            {
                type     = nonNullalbeType;
                fromType = nonNullableFromType;
            }
            return(ConversionCache.GetImplicitConversion(fromType, type) != null);
        }
Esempio n. 2
0
 /// <summary>
 /// 确定当前的 <see cref="System.Type"/> 的实例是否可以从指定 <see cref="System.Type"/>
 /// 的实例进行强制类型转换。
 /// </summary>
 /// <param name="type">要判断的实例。</param>
 /// <param name="fromType">要与当前类型进行比较的类型。</param>
 /// <returns>如果当前 <see cref="System.Type"/> 可以从 <paramref name="fromType"/>
 /// 的实例分配或进行强制类型转换,则为 <c>true</c>;否则为 <c>false</c>。</returns>
 /// <remarks>
 /// 判断类型间能否进行显式类型转换的算法来自于 《CSharp Language Specification》v5.0
 /// 的第 6.2 节,更多信息可以参考我的博客文章
 /// <see href="http://www.cnblogs.com/JFToolKit/archive/p/TypeAssignableFrom.html">
 /// 《C# 判断类型间能否隐式或强制类型转换,以及开放泛型类型转换》</see>。</remarks>
 /// <example>
 /// 下面是 <see cref="IsImplicitFrom"/> 方法的一些实例。
 /// <code>
 /// Console.WriteLine(typeof(uint).IsExplicitFrom(typeof(object))); // True
 /// Console.WriteLine(typeof(short).IsExplicitFrom(typeof(int))); // True
 /// Console.WriteLine(typeof(int).IsExplicitFrom(typeof(long?))); // True
 /// Console.WriteLine(typeof(long).IsExplicitFrom(typeof(TestClass))); // True
 /// class TestClass {
 ///     public static explicit operator int(TestClass t) { return 1; }
 /// }
 /// </code>
 /// </example>
 /// <seealso href="http://www.cnblogs.com/JFToolKit/archive/p/TypeAssignableFrom.html">
 /// 《C# 判断类型间能否隐式或强制类型转换,以及开放泛型类型转换》</seealso>
 public static bool IsExplicitFrom(this Type type, Type fromType)
 {
     if (type == null || fromType == null)
     {
         return(false);
     }
     // 标识转换。
     if (type == fromType)
     {
         return(true);
     }
     // 对引用类型的支持。
     if (type.IsByRef)
     {
         type = type.GetElementType();
     }
     if (fromType.IsByRef)
     {
         fromType = type.GetElementType();
     }
     // 总是可以与 Object 进行显示类型转换。
     if (type.Equals(typeof(object)) || fromType.Equals(typeof(object)))
     {
         return(true);
     }
     // 对 Nullable<T> 的支持。
     IsNullableType(ref type);
     IsNullableType(ref fromType);
     // 显式枚举转换。
     if (type.IsEnumExplicitFrom(fromType))
     {
         return(true);
     }
     // 判断是否可以进行标准显式转换。
     if (IsStandardExplicitFrom(type, fromType))
     {
         return(true);
     }
     // 对显式类型转换运算符进行判断。
     return(ConversionCache.GetExplicitConversion(fromType, type) != null);
 }
Esempio n. 3
0
        /// <summary>
        /// 返回指定类型的对象,其值等效于指定对象。参数提供区域性特定的格式设置信息。
        /// 只对允许进行隐式类型转换。
        /// </summary>
        /// <param name="value">要转换的对象。</param>
        /// <param name="conversionType">要返回的对象的类型。</param>
        /// <param name="provider">一个提供区域性特定的格式设置信息的对象。</param>
        /// <returns>一个对象,其类型为 <paramref name="conversionType"/>,
        /// 并且其值等效于 <paramref name="value"/>。</returns>
        internal static object ImplicitChangeType(object value, Type conversionType, IFormatProvider provider)
        {
            Type nonNullableType;

            if (BasicChangeType(ref value, conversionType, out nonNullableType))
            {
                return(value);
            }
            Type type = value.GetType();
            // 尝试标准隐式类型转换。
            bool   success;
            object result = StandardImplicitChangeType(value, type, nonNullableType, provider, out success);

            if (success)
            {
                return(result);
            }
            // 对隐式类型转换运算符进行判断。
            ConversionMethod method = ConversionCache.GetImplicitConversion(type, conversionType);

            if (method != null)
            {
                value = MethodInfo.GetMethodFromHandle(method.Method).Invoke(null, new object[] { value });
                if (value != null)
                {
                    type = value.GetType();
                    if (type != nonNullableType)
                    {
                        // 处理用户定义隐式类型转换之后的标准隐式类型转换。
                        value = StandardImplicitChangeType(value, type, nonNullableType, provider, out success);
                    }
                }
                return(value);
            }
            throw CommonExceptions.ConvertInvalidValue(value, conversionType);
        }
Esempio n. 4
0
        /// <summary>
        /// 返回指定类型的对象,其值等效于指定对象。参数提供区域性特定的格式设置信息。
        /// 支持可空类型、枚举和用户自定义类型转换。
        /// </summary>
        /// <param name="value">要转换的对象。</param>
        /// <param name="conversionType">要返回的对象的类型。</param>
        /// <param name="provider">一个提供区域性特定的格式设置信息的对象。</param>
        /// <returns>一个对象,其类型为 <paramref name="conversionType"/>,
        /// 并且其值等效于 <paramref name="value"/>。</returns>
        /// <overloads>
        /// <summary>
        /// 返回指定类型的对象,其值等效于指定对象。支持可空类型、枚举和用户自定义类型转换。
        /// </summary>
        /// </overloads>
        public static object ChangeType(object value, Type conversionType, IFormatProvider provider)
        {
            Type nonNullableType;

            if (BasicChangeType(ref value, conversionType, out nonNullableType))
            {
                return(value);
            }
            Type type = value.GetType();

            // 尝试显示枚举转换。
            if (conversionType.IsEnumExplicitFrom(type))
            {
                if (conversionType.IsEnum)
                {
                    // Enum.ToObject 不支持 char, float, double 和 decimal。
                    switch (Type.GetTypeCode(type))
                    {
                    case TypeCode.Char:
                        value = (ushort)(char)value;
                        break;

                    case TypeCode.Single:
                        value = (long)(float)value;
                        break;

                    case TypeCode.Double:
                        value = (long)(double)value;
                        break;

                    case TypeCode.Decimal:
                        value = (long)(decimal)value;
                        break;
                    }
                    return(Enum.ToObject(conversionType, value));
                }
                return(Convert.ChangeType(value, conversionType, provider));
            }
            // 尝试标准显式类型转换。
            bool   success;
            object result = StandardExplicitChangeType(value, type, nonNullableType, provider, out success);

            if (success)
            {
                return(result);
            }
            // 对显式类型转换运算符进行判断。
            ConversionMethod method = ConversionCache.GetExplicitConversion(type, conversionType);

            if (method != null)
            {
                value = MethodBase.GetMethodFromHandle(method.Method).Invoke(null, new [] { value });
                if (value != null)
                {
                    type = value.GetType();
                    if (type != nonNullableType)
                    {
                        // 处理用户定义显式类型转换之后的标准显式类型转换。
                        value = StandardExplicitChangeType(value, type, nonNullableType, provider, out success);
                    }
                }
                return(value);
            }
            // 尝试其他支持的转换。
            return(Convert.ChangeType(value, conversionType, provider));
        }