如何发射新结构

How to emit new structure

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();
}