【问题标题】:How do you create a delegate based on a lambda using reflection?如何使用反射创建基于 lambda 的委托?
【发布时间】:2017-01-23 18:01:28
【问题描述】:

我有以下课程(我无法更改它们,它们不在我的控制范围内):

public abstract class BusinessBase { }
public class A : BusinessBase { }
public class B : BusinessBase { }

public class FooOne
{
    public void Foo<T>(FooDelegates.Func<T> func) where T : BusinessBase { ... }
}

public class FooTwo
{
    public void Foo<T>(FooDelegates.Func<T> func) where T : BusinessBase { ... }
}

public static class FooDelegates
{
    public delegate TResult Func<TResult>();
}

创建委托和调用方法非常简单:

var f1 = new FooOne();
f1.Foo(() => new A());

但是,尝试使用反射来做到这一点被证明有点复杂。我有以下似乎无法完成的功能:

public class GenericHelper
{
    // Parent can be A or B or etc...
    // Child is FooOne or FooTwo or etc...
    public void Relate(object parent, object child)
    {
        var mi = child.GetType().GetMethod("Foo");
        var gmi = mi.MakeGenericMethod(parent.GetType());

        // This next part obviously won't compile...
        var del = typeof(FooDelegates.Func<>).MakeGenericType(parent.GetType());
        FooDelegates.Func<parent.GetType()> del = () => parent;
        gmi.Invoke(child, new object[] { del });
    }
}

如何正确生成FooDelegates.Func&lt;T&gt;,其中T 是父类型,并且我有一个匿名方法作为分配的方法?

【问题讨论】:

  • 你需要创建和Compile()一个表达式树

标签: c# .net reflection lambda delegates


【解决方案1】:

您可以在运行时使用表达式树来编译新函数:

Expression.Lambda(del, Expression.Constant(parent)).Compile()

【讨论】:

  • del 是代表类型的 Type。您需要从Compile() 传递已编译的委托
  • 经过修正和调整,非常接近。我得到了一个不同的错误:System.ArgumentException: Object of type 'Expression1[...] 不能转换为 [...]`。
  • 听起来你没有打电话给Compile()
猜你喜欢
  • 1970-01-01
  • 2011-03-02
  • 2012-06-04
  • 2011-03-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多