为什么在c#中强制事件订阅者具有特定的签名?
本文关键字:事件 为什么 | 更新日期: 2023-09-27 18:15:32
声明一个事件需要一个委托,订阅者将遵循这个委托(据我所知):
public delegate void SomeEventHandler(object source, EventArgs args);
public event SomeEventHandler EventHappend;
但是我们为什么需要这个委托呢?为什么不让任何带有任何签名的方法订阅事件呢?
以身作则…
class A
{
public event EventHappend; // Invalid C# but let's pretend it could work
public void DoSomething()
{
...
if (EventHappend != null)
{
// What should ??? be replaced with?
EventHappend(???);
}
}
}
class B
{
public B()
{
new A().EventHappend += EventHandler;
}
public void EventHandler(int anInt)
...
}
class C
{
public C()
{
new A().EventHappend += EventHandler;
}
public void EventHandler(string aString)
...
}
应该??被替换为处理B和C的情况(参数中的int或字符串)?
为什么不让任何带有签名的方法订阅事件呢?
那么发送方如何知道要向订阅者传递哪些参数呢?
你可能知道,也可能不知道,这就是你如何引发你在问题中声明的事件:
EventHappened(this, new EventArgs());
当你引发一个事件时,你需要传递参数给它!假设您允许任何类型的方法订阅事件,那么我将使用此方法订阅EventHappened
:
private void Foo(object sender, EventArgs e, int someNumber) {
Console.WriteLine(someNumber);
}
当事件被触发时,将打印什么?没人知道!事件的发送方没有传递int参数!
你可以说
那么当我触发事件时,我将传递一个额外的int参数!
如果有另一个方法也订阅该事件,如:
private void Bar(object sender, EventArgs e, List<string> myList) {
Console.WriteLine(myList);
}
这样,你的int参数与List<string>
不兼容!
" c#不是Javascript。你不能只传递2个参数给一个需要3"的方法- sweep 2016
委托类型在这里是为了确保事件的发送方传递正确的参数,而订阅者是一个可以接受传递的参数作为参数的方法。
因为调用方希望能够将一组参数传递给被调用方。因此,调用方和被调用方都需要就某种契约达成一致,该契约定义了调用方期望和被调用方提供的参数集——而被调用方恰好是委托。
委托的"实例"无非是说:看这里,这里有一个"指针",指向一个符合我签名的方法,通过调用我,你可以执行这个方法。
示例:调用方想要传递自己的实例,一个string
和一个int
给被调用方。如果被调用方只接受bool
,那该如何工作呢?
可以引入约定,每个事件处理程序都需要遵守签名:
public void Method(object sender, EventArgs e);
使以下事件声明语法始终有效:
public event EventHandler<EventArgs> MyEvent;
但是在很多情况下,如果你想传递任何有效负载给被调用者,你需要创建一个来自EventArgs
的类。