【问题标题】:How to compile a lambda expression into a dynamically created class如何将 lambda 表达式编译为动态创建的类
【发布时间】:2019-01-03 08:46:17
【问题描述】:

我正在尝试使用反射发射创建一个类的扩展。

而且它有点工作。

var extendwith = new List<Type>();
extendwith.Add(typeof(object));
var t = Utils.DynamicInherit<BaseTest>("Extended",typeof(UtilsTest).GetMethod(nameof(Testing)), extendwith);

var instance = Activator.CreateInstance(t, new TestClass(), new { A=1 });


public class BaseTest
{
    public readonly TestClass testClass;

    public object IsNotNull;

    public BaseTest(TestClass testClass)
    {
        this.testClass = testClass;
    }
}

public static void Testing(BaseTest baseTest, List<object> objects)
    {
        foreach(var t in objects)
        {
            baseTest.IsNotNull = t;
        }
    }

这里发生的情况是从 DynamicInherit 方法返回的类型 (t) 现在将继承自 BaseTest 类并具有包含 2 个参数(TestClass、Object)的构造函数

静态方法Testing 将在“构造类型”的构造函数内部调用。 使用此 IL 代码调用它。

constructorBuilder.Emit(OpCodes.Ldarg_0); //The this a referance to the created base class
constructorBuilder.Emit(OpCodes.Ldloc_0); //Reference to a List<Objects> that is passed in thorugh the constructor
constructorBuilder.Emit(OpCodes.Call, constructor); //The function to be called.. in this case the "public static void Testing(BaseTest baseTest, List<object> objects)"

这“按预期”工作,但我想将其更改为使用 lamda 表达式而不是静态函数..

var t = Utils.DynamicInherit<BaseTest>("Extended",(baseO, objects) => {foreach(var t in objects)
        {
            baseTest.IsNotNull = t;
        }} , 
        extendwith);

我知道我必须换行

constructorBuilder.Emit(OpCodes.Call, constructor); 

但我无法弄清楚如何...... 有什么建议吗???

【问题讨论】:

    标签: c# lambda reflection expression-trees


    【解决方案1】:

    给定

    Action<BaseText,List<object>> f = (BaseTest baseO, List<object> objects) => {
        foreach(var t in objects) {
            baseTest.IsNotNull = t;
        }
    };
    

    那么f.Method应该是我认为你需要的:

    var t = Utils.DynamicInherit<BaseTest>("Extended",f.Method, extendwith);
    

    或者,您可以将它们全部组合起来:

    var t = Utils.DynamicInherit<BaseTest>("Extended",((Action<BaseTest,List<object>>)((baseO, objects) => {foreach(var t in objects)
        {
            baseTest.IsNotNull = t;
        }})).Method,
        extendwith);
    

    使用我拥有的实用程序类使其更易于阅读:

    public static class To {
        public static Func<TResult> Func<TResult>(Func<TResult> func) => func;
        public static Func<T, TResult> Func<T, TResult>(Func<T, TResult> func) => func;
        public static Func<T1, T2, TResult> Func<T1, T2, TResult>(Func<T1, T2, TResult> func) => func;
        public static Func<T1, T2, T3, TResult> Func<T1, T2, T3, TResult>(Func<T1, T2, T3, TResult> func) => func;
        public static Func<T1, T2, T3, T4, TResult> Func<T1, T2, T3, T4, TResult>(Func<T1, T2, T3, T4, TResult> func) => func;
        public static Func<T1, T2, T3, T4, T5, TResult> Func<T1, T2, T3, T4, T5, TResult>(Func<T1, T2, T3, T4, T5, TResult> func) => func;
        public static Func<T1, T2, T3, T4, T5, T6, TResult> Func<T1, T2, T3, T4, T5, T6, TResult>(Func<T1, T2, T3, T4, T5, T6, TResult> func) => func;
        public static Func<T1, T2, T3, T4, T5, T6, T7, TResult> Func<T1, T2, T3, T4, T5, T6, T7, TResult>(Func<T1, T2, T3, T4, T5, T6, T7, TResult> func) => func;
        public static Func<T1, T2, T3, T4, T5, T6, T7, T8, TResult> Func<T1, T2, T3, T4, T5, T6, T7, T8, TResult>(Func<T1, T2, T3, T4, T5, T6, T7, T8, TResult> func) => func;
        public static Action<T> Action<T>(Action<T> act) => act;
        public static Action<T1, T2> Action<T1, T2>(Action<T1, T2> act) => act;
        public static Action<T1, T2, T3> Action<T1, T2, T3>(Action<T1, T2, T3> act) => act;
        public static Action<T1, T2, T3, T4> Action<T1, T2, T3, T4>(Action<T1, T2, T3, T4> act) => act;
        public static Action<T1, T2, T3, T4, T5> Action<T1, T2, T3, T4, T5>(Action<T1, T2, T3, T4, T5> act) => act;
        public static Action<T1, T2, T3, T4, T5, T6> Action<T1, T2, T3, T4, T5, T6>(Action<T1, T2, T3, T4, T5, T6> act) => act;
        public static Action<T1, T2, T3, T4, T5, T6, T7> Action<T1, T2, T3, T4, T5, T6, T7>(Action<T1, T2, T3, T4, T5, T6, T7> act) => act;
        public static Action<T1, T2, T3, T4, T5, T6, T7, T8> Action<T1, T2, T3, T4, T5, T6, T7, T8>(Action<T1, T2, T3, T4, T5, T6, T7, T8> act) => act;
    }
    

    那么你就有了:

    var t = Utils.DynamicInherit<BaseTest>("Extended", To.Action((baseO, objects) => {
        foreach(var t in objects) {
            baseTest.IsNotNull = t;
        }}).Method,
        extendwith);
    

    【讨论】:

    • 聪明的事情是创建一组静态泛型方法.. 没想到:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-14
    相关资源
    最近更新 更多