【发布时间】:2013-08-25 12:14:00
【问题描述】:
我最近开始明白 C# 的“事件”确实如此。老实说,这不是什么。总结一下我的发现:event 关键字只是一个仅适用于委托的修饰符。
因此,事件的所有“魔法”都是委托的操作。而已。我已经阅读了很多 Microsoft 文档,但没有一个句子可以如此简洁地总结。为了继续我的发现,delegate、class 和 struct 都在同一个“级别”上。它们是定义“对象”的方法。我不是指类型中的“对象”,而是“某物”的封装概念。就像在说面向对象编程时如何使用“对象”这个词。
无论如何,“对象”有一定的修饰语。例如,sealed、readonly、virtual、static 等...可以在here 找到此列表。在委托的情况下,它有一个额外的称为事件。 Event 使得当一个委托被声明为一个类的一部分时,它只根据赋予事件的访问修饰符公开 add 和 remove 方法。这些方法的定义类似于属性的get 和set。委托的其他操作(赋值、读取访问、方法调用等)只允许在声明事件委托的类中。我觉得有趣的另一件事是,所有委托都有方法 Invoke、BeginInvoke 和 EndInvoke,但您无法在 Visual Studio 中导航以查看它们,我也找不到描述它们的文档...
好的。所以在了解了这一切之后,除了修改委托的访问方式之外,使用 event 关键字还有什么好处?似乎在很多情况下,我最好简单地声明一个没有 event 关键字的委托。我最近遇到的一种情况是我想创建一个包含 2 个事件的抽象基类。从这个基类派生的任何类都应该能够像它们自己一样使用事件,类似于暴露给派生类的类的任何其他对象(也称为非私有,除非派生类在另一个程序集,并且该对象被声明为内部的)。
基本上,我希望派生类将这些事件用作自己的事件。这样做的唯一方法是将事件的支持变量公开为受保护的,因此派生类可以引发事件。查看代码,这似乎很愚蠢,因为我基本上定义了两次委托;一次作为受保护的字段,另一次作为公共事件。我想,
创建一个名为 Event 的类不是更好吗? 构造函数中Action的参数?返回的操作相当于许多人作为委托的扩展方法所做的 Raise,它检查委托是否为空,然后调用委托。 Event 上唯一的公共方法是 Add 和 Remove,用于附加委托并将它们从底层委托 (+=、-=) 中删除。类可以将这些事件作为属性,例如,
public Event SomethingHappened { get; private set; }
以便只有该类可以重新分配事件。或者公共只读字段也同样有效。从构造函数返回的 out 参数由类存储并在类想要引发事件时调用。我知道这是一个很糟糕的解决方法,但它会完成工作,并且允许事件不仅作为参数传递,而且如果基类将其定义为受保护,则允许派生类调用 Raise 方法。
TLDR:
除了修改委托的访问方式之外,使用 event 关键字还有什么好处?
【问题讨论】:
-
"other than for modifying how the delegate can be accessed"这对你来说还不够吗?这足以让我使用它。此外,它有助于更有效地传达成员的语义意图。 -
见csharpindepth.com/Articles/Chapter2/Events.aspx 有点像比较属性和字段。
-
这个问题似乎是题外话,因为它不是一个问题。这是一个咆哮。
-
它不是一个修饰符,它是一个访问器,它限制了外部代码可以用委托做的事情的数量。只需添加和删除事件处理程序,仅此而已。就像属性是字段的访问器一样。它可以阻止行为不端的代码破坏其他代码进行的事件订阅。
标签: c# events delegates keyword