是否可以使用反射来挂接匿名委托?

时间:2011-03-01 13:13:31

标签: c# reflection delegates

从这个MSDN article开始,有很多方法可以使用反射来连接委托。

似乎最好的方法是使用CreateDelegate方法:

Delegate d = Delegate.CreateDelegate(delegateType, targetObject, handlerMethodName);

在正常情况下,我将指向targetObject类中的处理程序方法。 但是,如果代表是匿名创建的呢?例如:

public delegate void SelectedVehiclesCollectionDelegate(string query, List<Vehicles> list);
...
myObject.SelectedVehiclesCollection = (query, list) =>
                    {
                      //assign list of vehicles to list matching query
                    };  

委托引用的类定义中没有方法。我需要调用这个在运行时未知的委托,获取项目列表就是结果。

好的,看起来我的术语得到了我的最好。不打算创建一个处理程序,但调用已经存在的东西(Tomas Petricek的答案仍然给了我一些很好的见解)。

2 个答案:

答案 0 :(得分:2)

鉴于您的评论,听起来这是关于调用代理而非创建代理,在这种情况下,Delegate.DynamicInvoke可能是您所追求的,如果你真的在编译时不知道相关的委托类型。

如果你知道相关的委托类型,而不是属性名称,你可以强制转换:

MyDelegate handler = (MyDelegate) propertyInfo.GetValue(obj, null);
handler(...); // Call as normal

答案 1 :(得分:1)

在封面下,匿名委托被编译成一个类,因此仍然有一些目标对象和方法名称。该类还可以包含一些其他字段 - 如果您在方法中捕获局部变量,它将成为该类的成员。

如果你想有一个简单的方法来创建匿名委托并使用Reflection连接它们,你可以编写一个非常简单的类:

class Closure {
  public Action Operation { get; set; }
  public void Invoke() { Operation(); }
}

然后你可以使用类似的东西创建一个操作(并使用Invoke作为目标方法):

var op = new Closure { Operation = delegate() { .. } };

这取决于你究竟想要做什么 - 使用Reflection挂钩事件的关键是你只需要一些你想要运行的方法。如果您有代理人(例如Action),那么您可以直接使用它。如果要在编译时创建一个未知的委托,这样的类可能很有用。