C# 如何使用CIL将POCO转换为数组?

C# 如何使用CIL将POCO转换为数组?,c#,.net,poco,cil,dynamicmethod,C#,.net,Poco,Cil,Dynamicmethod,这是我第一次涉足生成的CIL,所以请容忍我的无知。我正在寻找一种简单的DynamicMethod,它可以读取POCO的字段,并将它们填充到对象[]。不需要进行类型转换。我已经把我能做的都准备好了,你能帮我完成吗 Type t = typeof(POCO); DynamicMethod dm = new DynamicMethod("Get" + memberName,typeof(MemberType), new Type[] { objectType }, objectType); ILGe

这是我第一次涉足生成的CIL,所以请容忍我的无知。我正在寻找一种简单的DynamicMethod,它可以读取POCO的字段,并将它们填充到
对象[]
。不需要进行类型转换。我已经把我能做的都准备好了,你能帮我完成吗

Type t = typeof(POCO);

DynamicMethod dm = new DynamicMethod("Get" + memberName,typeof(MemberType), new Type[] { objectType }, objectType);
ILGenerator il = dm.GetILGenerator();

// Load the instance of the object (argument 0) onto the stack
il.Emit(OpCodes.Ldarg_0);

// get fields
FieldInfo[] fields = t.GetFields();

// how do I create an array (object[]) at this point?

// per field
foreach (var pi in fields) {

    // Load the value of the object's field (fi) onto the stack
    il.Emit(OpCodes.Ldfld, fi);

    // how do I add it into the array?

}

// how do I push the array onto the stack?

// return the array
il.Emit(OpCodes.Ret);

可以使用此代码生成已编译的lambda表达式

public static Func<T, object[]> MakeFieldGetter<T>() {
    var arg = Expression.Parameter(typeof(T), "arg");
    var body = Expression.NewArrayInit(
        typeof(object)
    ,   typeof(T).GetFields().Select(f => (Expression)Expression.Convert(Expression.Field(arg, f), typeof(object)))
    );
   return (Func<T, object[]>)Expression
        .Lambda(typeof(Func<T, object[]>), body, arg)
        .Compile();
}
这段代码也会生成IL,但它不是手动编写的,而是让
Lambda
Compile
方法为您的应用程序生成IL


下面是一个。

有一个使用表达式树的简单解决方案,它使您成为一个编译的lambda。您是否对此感兴趣,或者您是在专门寻找发射解决方案?如果您想知道如何在IL中执行某些操作,请使用C#编写相同的代码并查看生成的IL。@Geotarget我认为您混淆了LINQ和LINQ表达式树。编译后的表达式树与手动发出的代码一样快。@Geotarget它们不是。如果编译lambda表达式,将得到一个委托,与使用
DynamicMethod
@dasblinkenlight-添加答案完全相同。有人帮忙总比没有好。
object[] GetFields(MyClass arg) {
    return new object[] {
        // The list of fields is generated through reflection
        // at the time of building the lambda. There is no reflection calls
        // inside the working lambda, though: the field list is "baked into"
        // the expression as if it were hard-coded manually.
        (object)arg.Field1
    ,   (object)arg.Field2
    ,   (object)arg.Field3
    };
}