public static void EmitConvertToType(ILGenerator il, Type typeFrom, Type typeTo, bool isChecked) { if (TypeUtil.AreEquivalent(typeFrom, typeTo)) { return; } if (typeFrom == typeof(void) || typeTo == typeof(void)) { throw new InvalidOperationException(); } bool isTypeFromNullable = TypeUtil.IsNullableType(typeFrom); bool isTypeToNullable = TypeUtil.IsNullableType(typeTo); Type nnExprType = TypeUtil.GetNonNullableType(typeFrom); Type nnType = TypeUtil.GetNonNullableType(typeTo); if (typeFrom.IsInterface || // interface cast typeTo.IsInterface || typeFrom == typeof(object) || // boxing cast typeTo == typeof(object) || typeFrom == typeof(System.Enum) || typeFrom == typeof(System.ValueType) || TypeUtil.IsLegalExplicitVariantDelegateConversion(typeFrom, typeTo)) { EmitCastToType(il, typeFrom, typeTo); } else if (isTypeFromNullable || isTypeToNullable) { EmitNullableConversion(il, typeFrom, typeTo, isChecked); } else if (!(TypeUtil.IsConvertible(typeFrom) && TypeUtil.IsConvertible(typeTo)) // primitive runtime conversion && (nnExprType.IsAssignableFrom(nnType) || // down cast nnType.IsAssignableFrom(nnExprType))) // up cast { EmitCastToType(il, typeFrom, typeTo); } else if (typeFrom.IsArray && typeTo.IsArray) { // See DevDiv Bugs #94657. EmitCastToType(il, typeFrom, typeTo); } else { EmitNumericConversion(il, typeFrom, typeTo, isChecked); } }