var instanceType = typeof(T);
LocalBuilder instanceBuilder = il.DeclareLocal(instanceType);// T
if (instanceType.IsValueType)
{
il.Emit(OpCodes.Ldloca, instanceBuilder);
il.Emit(OpCodes.Initobj, instanceBuilder);
il.Emit(OpCodes.Stloc_S, instanceBuilder);
}
else
{
il.Emit(OpCodes.Newobj, instanceType.GetConstructor(Type.EmptyTypes));
il.Emit(OpCodes.Stloc_S, instanceBuilder);
}
il.Emit(OpCodes.Ldstr, "Test");
il.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { TypeUtil._StringType }));
il.Emit(OpCodes.Ldloc, instanceBuilder);
il.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { TypeUtil._ObjectType }));
任何人都可以告诉我如何通过默认构造函数发射新的结构?
您所需要的只是ldloca
(或ldflda
/ldsflda
(和initobj
。没有什么可存储的(stloc_s
是不必要的(。initobj
的第二个参数是 type 令牌,而不是地址:
using System;
using System.Reflection.Emit;
static class Program
{
static void Main()
{
var method = new DynamicMethod("create", typeof(Foo), new[] { typeof(int) });
var il = method.GetILGenerator();
var local = il.DeclareLocal(typeof(Foo));
// initialize the local (essentially: the default ctor)
il.Emit(OpCodes.Ldloca_S, local);
il.Emit(OpCodes.Initobj, typeof(Foo));
// assign the parameter value to the property
il.Emit(OpCodes.Ldloca_S, local);
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Call,
typeof(Foo).GetProperty(nameof(Foo.Id)).GetSetMethod());
// load, box, and call CWL
il.Emit(OpCodes.Ldloc_S, local);
il.Emit(OpCodes.Box, typeof(Foo));
il.Emit(OpCodes.Call, typeof(Console).GetMethod(
nameof(Console.WriteLine), new[] { typeof(object) }));
// return the value of the
il.Emit(OpCodes.Ldloc_S, local);
il.Emit(OpCodes.Ret);
// call the emitted method
var del = (Func<int, Foo>)method.CreateDelegate(typeof(Func<int, Foo>));
var foo = del(42);
}
}
public struct Foo
{
public int Id { get; set; } // not usually a good idea, note
public override string ToString() => Id.ToString();
}