我创建了一个基于事件的系统,其中一个类将提供一堆事件,另一个类及其成员方法可以附加到第一个类作为其事件处理程序,并且…我只是想做这样的事情
if(isMethodCompatibleToEvent(...))
{
connectMethodToEvent(...)
}
通过反射,连接是这样完成的:
void connectMethodToEvent(object methodTarget, MethodInfo mi,
object eventTarget, EventInfo ei)
{
Delegate handler = Delegate.CreateDelegate(ei.EventHandlerType, methodTarget, mi);
ei.AddEventHandler(eventTarget, handler);
}
如果方法与事件不兼容,它将抛出异常,为了解决这个问题,我想在创建方法委托之前创建一些检查,但是如何呢?
bool isMethodCompatibleToEvent(object methodTarget, MethodInfo mi,
object eventTarget, EventInfo ei)
{
// HOW ?
}
- 形式参数个数必须相同
- 形式参数的"refness"必须相同。(从技术上讲,具有
out
参数的方法可以用于具有ref
参数的事件,反之亦然,但我不建议这样做。) - 各形式参数类型必须兼容。对于值类型,它们必须精确匹配。对于引用类型的形式形参,允许有逆变。也就是说,如果你有一个事件处理程序,它将传递一个长颈鹿给委托,委托被允许接受Animal。
- 返回类型的"void"必须相同;
void
只匹配void
- 对于非空返回类型,值类型必须完全匹配。对于返回引用类型的事件处理程序,允许协方差。也就是说,如果事件处理程序说它返回Animal而委托返回Giraffe,那就可以了。
这些不是所有的规则,但它们足以处理绝大多数常见情况
你需要比较方法和委托的签名(定义事件的类型):如果它们匹配,那么方法可以合并到事件中。
参数和返回类型的精确匹配显然是最简单的,但也要考虑隐式转换也可以应用(根据您的需求,使用Type.IsAssignableFrom
可能就足够了)。
检查c#语言规范中关于方法和事件类型兼容性的规则将是第一步。