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 }));
有人能通过默认构造函数告诉我如何发布新的结构吗?
答案 0 :(得分:0)
您需要的只是ldloca
(或ldflda
/ ldsflda
)和initobj
。无需存储(stloc_s
是不必要的)。 initobj
的第二个参数是类型标记,而不是地址:
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();
}