从这个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的答案仍然给了我一些很好的见解)。
答案 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
),那么您可以直接使用它。如果要在编译时创建一个未知的委托,这样的类可能很有用。