コード例 #1
0
        public static void EmitConvertToType(this ILGenerator ilGenerator, Type typeFrom, Type typeTo, bool isChecked = true)
        {
            if (ilGenerator == null)
            {
                throw new ArgumentNullException(nameof(ilGenerator));
            }
            if (typeFrom == null)
            {
                throw new ArgumentNullException(nameof(typeFrom));
            }
            if (typeTo == null)
            {
                throw new ArgumentNullException(nameof(typeTo));
            }

            var nnExprType = typeFrom.Unwrap();
            var nnType     = typeTo.Unwrap();

            if (nnType == nnExprType || nnType.IsEquivalentTo(nnExprType))
            {
                return;
            }

            if (typeFrom.IsInterface ||       // interface cast
                typeTo.IsInterface ||
                typeFrom == typeof(object) || // boxing cast
                typeTo == typeof(object) ||
                typeFrom == typeof(Enum) ||
                typeFrom == typeof(ValueType) ||
                TypeInfoUtils.IsLegalExplicitVariantDelegateConversion(typeFrom, typeTo))
            {
                ilGenerator.EmitCastToType(typeFrom, typeTo);
            }
            else if (typeFrom.IsNullableType() || typeTo.IsNullableType())
            {
                ilGenerator.EmitNullableConversion(typeFrom, typeTo, isChecked);
            }
            else if (!(typeFrom.IsConvertible() && typeTo.IsConvertible()) // primitive runtime conversion
                     &&
                     (nnExprType.GetTypeInfo().IsAssignableFrom(nnType) || // down cast
                      nnType.GetTypeInfo().IsAssignableFrom(nnExprType)))  // up cast
            {
                ilGenerator.EmitCastToType(typeFrom, typeTo);
            }
            else if (typeFrom.IsArray && typeTo.IsArray)
            {
                // See DevDiv Bugs #94657.
                ilGenerator.EmitCastToType(typeFrom, typeTo);
            }
            else
            {
                ilGenerator.EmitNumericConversion(typeFrom, typeTo, isChecked);
            }
        }