private static void EmitNullableToNullableConversion(this ILGenerator ilGenerator, TypeInfo typeFrom, TypeInfo typeTo, bool isChecked) { Label labIfNull = default(Label); Label labEnd = default(Label); LocalBuilder locFrom = null; LocalBuilder locTo = null; locFrom = ilGenerator.DeclareLocal(typeFrom.AsType()); ilGenerator.Emit(OpCodes.Stloc, locFrom); locTo = ilGenerator.DeclareLocal(typeTo.AsType()); // test for null ilGenerator.Emit(OpCodes.Ldloca, locFrom); ilGenerator.EmitHasValue(typeFrom.AsType()); labIfNull = ilGenerator.DefineLabel(); ilGenerator.Emit(OpCodes.Brfalse_S, labIfNull); ilGenerator.Emit(OpCodes.Ldloca, locFrom); ilGenerator.EmitGetValueOrDefault(typeFrom.AsType()); Type nnTypeFrom = TypeInfoUtils.GetNonNullableType(typeFrom); Type nnTypeTo = TypeInfoUtils.GetNonNullableType(typeTo); ilGenerator.EmitConvertToType(nnTypeFrom, nnTypeTo, isChecked); // construct result type ConstructorInfo ci = typeTo.GetConstructor(new Type[] { nnTypeTo }); ilGenerator.Emit(OpCodes.Newobj, ci); ilGenerator.Emit(OpCodes.Stloc, locTo); labEnd = ilGenerator.DefineLabel(); ilGenerator.Emit(OpCodes.Br_S, labEnd); // if null then create a default one ilGenerator.MarkLabel(labIfNull); ilGenerator.Emit(OpCodes.Ldloca, locTo); ilGenerator.Emit(OpCodes.Initobj, typeTo.AsType()); ilGenerator.MarkLabel(labEnd); ilGenerator.Emit(OpCodes.Ldloc, locTo); }
private static void EmitNullableToNonNullableStructConversion(this ILGenerator ilGenerator, TypeInfo typeFrom, TypeInfo typeTo, bool isChecked) { LocalBuilder locFrom = null; locFrom = ilGenerator.DeclareLocal(typeFrom.AsType()); ilGenerator.Emit(OpCodes.Stloc, locFrom); ilGenerator.Emit(OpCodes.Ldloca, locFrom); ilGenerator.EmitGetValue(typeFrom.AsType()); Type nnTypeFrom = TypeInfoUtils.GetNonNullableType(typeFrom); ilGenerator.EmitConvertToType(nnTypeFrom, typeTo.AsType(), isChecked); }
private static void EmitNonNullableToNullableConversion(this ILGenerator ilGenerator, TypeInfo typeFrom, TypeInfo typeTo, bool isChecked) { LocalBuilder locTo = null; locTo = ilGenerator.DeclareLocal(typeTo.AsType()); Type nnTypeTo = TypeInfoUtils.GetNonNullableType(typeTo); ilGenerator.EmitConvertToType(typeFrom.AsType(), nnTypeTo, isChecked); ConstructorInfo ci = typeTo.GetConstructor(new Type[] { nnTypeTo }); ilGenerator.Emit(OpCodes.Newobj, ci); ilGenerator.Emit(OpCodes.Stloc, locTo); ilGenerator.Emit(OpCodes.Ldloc, locTo); }