Reputation: 391
I am learning IL (intermediate language) for possible applications to a C# application.
Using c#, I am trying to generate a dynamic method to convert a DateOnly into a DateTime. In C#, it would just be:
public static DateTime ToDateTime(DateOnly dtOnly)
{
return dtOnly.ToDateTime(new TimeOnly(0));
}
My code is:
using System.Reflection.Emit;
namespace ConsoleApp2
{
public class MyModule
{
public static void CreateAndInvokeDynamicMethod()
{
var fuc = GenerateDateTimeFromDateOnly2();
DateOnly dt = new DateOnly(1974, 1, 17);
DateTime to = fuc.Invoke(dt);
return;
}
public static Func<DateOnly, DateTime> GenerateDateTimeFromDateOnly2()
{
Type[] methodArgs = { typeof(int) };
DynamicMethod methodBuilder = new DynamicMethod(
"JustATest",
typeof(DateTime),
new Type[] { typeof(DateOnly) },
typeof(MyModule).Module)
;
ILGenerator ilGenerator = methodBuilder.GetILGenerator();
// Load the DateOnly argument onto the stack
ilGenerator.Emit(OpCodes.Ldarg_0);
ilGenerator.Emit(OpCodes.Ldc_I4_0); // Load 0
ilGenerator.Emit(OpCodes.Ldc_I4_0); // Load 0
ilGenerator.Emit(OpCodes.Newobj, typeof(TimeOnly).GetConstructor(new Type[] { typeof(int), typeof(int) }));
//Now, I have a TimeOnly in the Stack
// Call the DateOnly.ToDateTime method
ilGenerator.EmitCall(OpCodes.Call, typeof(DateOnly).GetMethod("ToDateTime", new Type[] { typeof(TimeOnly) }), null);
ilGenerator.Emit(OpCodes.Ret);
return (Func<DateOnly, DateTime>)methodBuilder.CreateDelegate(typeof(Func<DateOnly, DateTime>));
}
}
}
When I invoke it, I get the error "Attempted to read or write protected memory. This is often an indication that other memory is corrupt"
Any Idea what's wrong in my code?
I also decompiled the c# into IL, but I don't see any relevant difference.
.method public hidebysig
instance valuetype [System.Runtime]System.DateTime ToDateTime (
valuetype [System.Runtime]System.DateOnly dtOn
) cil managed
{
// Method begins at RVA 0x206c
// Code size 20 (0x14)
.maxstack 3
.locals init (
[0] valuetype [System.Runtime]System.DateTime
)
IL_0000: nop
IL_0001: ldarga.s dtOn
IL_0003: ldc.i4.0
IL_0004: ldc.i4.0
IL_0005: newobj instance void [System.Runtime]System.TimeOnly::.ctor(int32, int32)
IL_000a: call instance valuetype [System.Runtime]System.DateTime [System.Runtime]System.DateOnly::ToDateTime(valuetype [System.Runtime]System.TimeOnly)
IL_000f: stloc.0
IL_0010: br.s IL_0012
IL_0012: ldloc.0
IL_0013: ret
} // end of method GenericClass::ToDateTime
Actually, I don't understand the need of an additional DateTime. Also, what's the purpose of an unconditional branch
IL_000f: stloc.0
IL_0010: br.s IL_0012
IL_0012: ldloc.0
Upvotes: 0
Views: 267