Esempio n. 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 typeFromInfo = typeFrom.GetTypeInfo();
            var typeToInfo   = typeTo.GetTypeInfo();

            var nnExprType = typeFromInfo.GetNonNullableType();
            var nnType     = typeToInfo.GetNonNullableType();

            if (TypeExtensions.AreEquivalent(typeFromInfo, typeToInfo))
            {
                return;
            }

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