Exemplo n.º 1
0
        /// <summary>
        /// 确定当前 <see cref="Type"/> 的实例是否可以从 <paramref name="fromType"/> 的实例显式类型转换得到。
        /// 这里仅考虑预定义的显式类型转换,不考虑由 <c>implicit</c> 运算符和 <c>explicit</c> 运算符指定的转换。
        /// </summary>
        /// <param name="type">当前类型。</param>
        /// <param name="fromType">要判断能否显式类型转换得到的类型。</param>
        /// <returns>如果当前 <see cref="Type"/> 的实例是否可以从 <paramref name="fromType"/>
        /// 的实例显式类型转换得到,则为 <c>true</c>;否则为 <c>false</c>。</returns>
        /// <exception cref="ArgumentNullException"><paramref name="type"/> 为 <c>null</c>。</exception>
        /// <exception cref="ArgumentNullException"><paramref name="fromType"/> 为 <c>null</c>。</exception>
        /// <remarks>
        /// 判断类型间能否进行显式类型转换的算法来自于 《CSharp Language Specification》v5.0
        /// 的第 6.1 节。</remarks>
        /// <example>
        /// 下面是 <see cref="IsExplicitFrom"/> 方法的一些实例。
        /// <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
        /// </code>
        /// </example>
        /// <seealso href="http://www.cnblogs.com/cyjb/archive/p/TypeAssignableFrom.html">
        /// 《C# 判断类型间能否隐式或强制类型转换,以及开放泛型类型转换》</seealso>
        public static bool IsExplicitFrom(this Type type, Type fromType)
        {
            CommonExceptions.CheckArgumentNull(type, "type");
            CommonExceptions.CheckArgumentNull(fromType, "fromType");
            Contract.EndContractBlock();
            Conversion conversion = ConversionFactory.GetPreDefinedConversion(fromType, type);

            return(conversion != null && conversion.ConversionType != ConversionType.None);
        }
Exemplo n.º 2
0
        /// <summary>
        /// 确定当前 <see cref="Type"/> 的实例是否可以从 <paramref name="fromType"/> 的实例隐式类型转换得到。
        /// 这里仅考虑预定义的隐式类型转换,不考虑由 <c>implicit</c> 运算符指定的转换。
        /// </summary>
        /// <param name="type">当前类型。</param>
        /// <param name="fromType">要判断能否隐式类型转换得到的类型。</param>
        /// <returns>如果当前 <see cref="Type"/> 的实例是否可以从 <paramref name="fromType"/>
        /// 的实例隐式类型转换得到,则为 <c>true</c>;否则为 <c>false</c>。</returns>
        /// <exception cref="ArgumentNullException"><paramref name="type"/> 为 <c>null</c>。</exception>
        /// <exception cref="ArgumentNullException"><paramref name="fromType"/> 为 <c>null</c>。</exception>
        /// <remarks>
        /// 判断类型间能否进行隐式类型转换的算法来自于 《CSharp Language Specification》v5.0
        /// 的第 6.1 节。</remarks>
        /// <example>
        /// 下面是 <see cref="IsImplicitFrom"/> 方法与 <see cref="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
        /// </code>
        /// </example>
        /// <seealso href="http://www.cnblogs.com/cyjb/archive/p/TypeAssignableFrom.html">
        /// 《C# 判断类型间能否隐式或强制类型转换,以及开放泛型类型转换》</seealso>
        public static bool IsImplicitFrom(this Type type, Type fromType)
        {
            CommonExceptions.CheckArgumentNull(type, nameof(type));
            CommonExceptions.CheckArgumentNull(fromType, nameof(fromType));
            Contract.EndContractBlock();
            var conversion = ConversionFactory.GetPreDefinedConversion(fromType, type);

            return(conversion != null && conversion.ConversionType.IsImplicit());
        }
Exemplo n.º 3
0
        /// <summary>
        /// 确定当前 <see cref="Type"/> 的实例是否可以从 <paramref name="fromType"/> 的实例显式类型转换得到。
        /// 这里仅考虑预定义的显式类型转换,不考虑由 <c>implicit</c> 运算符和 <c>explicit</c> 运算符指定的转换。
        /// </summary>
        /// <param name="type">当前类型。</param>
        /// <param name="fromType">要判断能否显式类型转换得到的类型。</param>
        /// <returns>如果当前 <see cref="Type"/> 的实例是否可以从 <paramref name="fromType"/>
        /// 的实例显式类型转换得到,则为 <c>true</c>;否则为 <c>false</c>。</returns>
        /// <exception cref="ArgumentNullException"><paramref name="type"/> 为 <c>null</c>。</exception>
        /// <exception cref="ArgumentNullException"><paramref name="fromType"/> 为 <c>null</c>。</exception>
        /// <remarks>
        /// 判断类型间能否进行显式类型转换的算法来自于 《CSharp Language Specification》v5.0
        /// 的第 6.1 节。</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
        /// </code>
        /// </example>
        /// <seealso href="http://www.cnblogs.com/cyjb/archive/p/TypeAssignableFrom.html">
        /// 《C# 判断类型间能否隐式或强制类型转换,以及开放泛型类型转换》</seealso>
        public static bool IsExplicitFrom(this Type type, Type fromType)
        {
            if (type == null)
            {
                throw CommonExceptions.ArgumentNull("type");
            }
            if (fromType == null)
            {
                throw CommonExceptions.ArgumentNull("otherType");
            }
            Contract.EndContractBlock();
            Conversion conversion = ConversionFactory.GetPreDefinedConversion(fromType, type);

            return(conversion != null && conversion.ConversionType != ConversionType.None);
        }
Exemplo n.º 4
0
        /// <summary>
        /// 获取转换类型的指令生成器,能够将栈顶的对象从 <paramref name="inputType"/> 转换为
        /// <paramref name="outputType"/>。
        /// </summary>
        /// <param name="il">IL 指令生成器。</param>
        /// <param name="inputType">要转换的对象的类型。</param>
        /// <param name="outputType">要将输入对象转换到的类型。</param>
        /// <param name="conversionType">类型转换类型的限制。</param>
        /// <returns>类型转换的指令生成器,如果不能进行类型转换则返回 <c>null</c>。</returns>
        internal static Converter GetConversion(this ILGenerator il, Type inputType, Type outputType,
                                                ConversionType conversionType)
        {
            Contract.Requires(il != null && inputType != null && outputType != null);
            Contract.Requires(conversionType == ConversionType.Implicit ||
                              conversionType == ConversionType.Explicit ||
                              conversionType == ConversionType.UserDefined);
            Conversion conversion = conversionType == ConversionType.UserDefined ?
                                    ConversionFactory.GetConversion(inputType, outputType) :
                                    ConversionFactory.GetPreDefinedConversion(inputType, outputType);

            if (conversion == null || conversion.ConversionType > conversionType)
            {
                return(null);
            }
            return(new Converter(conversion, il, inputType, outputType));
        }
Exemplo n.º 5
0
        /// <summary>
        /// 将栈顶的对象从 <paramref name="inputType"/> 转换为 <paramref name="outputType"/>。
        /// </summary>
        /// <param name="il">IL 指令生成器。</param>
        /// <param name="inputType">要转换的对象的类型。</param>
        /// <param name="outputType">要将输入对象转换到的类型。</param>
        /// <param name="isChecked">是否执行溢出检查。</param>
        /// <param name="conversionType">类型转换类型的限制。</param>
        internal static void EmitConversion(this ILGenerator il, Type inputType, Type outputType, bool isChecked,
                                            ConversionType conversionType)
        {
            Contract.Requires(il != null && inputType != null && outputType != null);
            Contract.Requires(conversionType == ConversionType.Implicit ||
                              conversionType == ConversionType.Explicit ||
                              conversionType == ConversionType.UserDefined);
            Conversion conversion = conversionType == ConversionType.UserDefined ?
                                    ConversionFactory.GetConversion(inputType, outputType) :
                                    ConversionFactory.GetPreDefinedConversion(inputType, outputType);

            if (conversion == null || conversion.ConversionType > conversionType)
            {
                throw CommonExceptions.InvalidCast(inputType, outputType);
            }
            if (conversion is FromNullableConversion)
            {
                il.EmitGetAddress(inputType);
            }
            conversion.Emit(il, inputType, outputType, isChecked);
        }
Exemplo n.º 6
0
        /// <summary>
        /// 构造类型转换器。
        /// </summary>
        /// <param name="conversion">使用的类型转换。</param>
        /// <param name="inputType">要转换的对象的类型。</param>
        /// <param name="outputType">要将输入对象转换到的类型。</param>
        /// <param name="isChecked">是否执行溢出检查。</param>
        /// <param name="buildGeneric"><c>true</c> 表示需要生成泛型类型转换委托;<c>false</c>
        /// 表示需要生成非泛型的类型转换委托。</param>
        /// <returns>将对象从 <paramref name="inputType"/> 类型转换为 <paramref name="outputType"/> 类型的转换器。</returns>
        private static Delegate BuildConverter(Conversion conversion, Type inputType, Type outputType, bool isChecked,
                                               bool buildGeneric)
        {
            Contract.Requires(conversion != null && inputType != null && outputType != null);
            Contract.Ensures(Contract.Result <Delegate>() != null);
            DynamicMethod method = new DynamicMethod("Converter", buildGeneric ? outputType : typeof(object),
                                                     new[] { buildGeneric?inputType: typeof(object) }, true);
            ILGenerator il            = method.GetILGenerator();
            bool        passByAddress = conversion is FromNullableConversion;

            if (passByAddress && (buildGeneric || !inputType.IsValueType))
            {
                il.Emit(OpCodes.Ldarga_S, (byte)0);
            }
            else
            {
                il.Emit(OpCodes.Ldarg_0);
            }
            if (buildGeneric)
            {
                conversion.Emit(il, inputType, outputType, isChecked);
                il.Emit(OpCodes.Ret);
                return(method.CreateDelegate(typeof(Converter <,>).MakeGenericType(inputType, outputType)));
            }
            // 从 object 拆箱得到值类型。
            ConversionFactory.GetPreDefinedConversion(typeof(object), inputType).Emit(il, typeof(object), inputType, isChecked);
            if (passByAddress)
            {
                il.EmitGetAddress(inputType);
            }
            conversion.Emit(il, inputType, outputType, isChecked);
            // 值类型装箱为 object。
            if (outputType.IsValueType)
            {
                il.Emit(OpCodes.Box, outputType);
            }
            il.Emit(OpCodes.Ret);
            return(method.CreateDelegate(typeof(Converter <object, object>)));
        }