5

我是 C# events 和代表的初学者。如果您查看我用来了解事件的 URL,那么很少有问题是有意义的。

  1. 我可以举办一个没有与之关联的代表的活动吗?我发现的例子总是把它们放在一起。

  2. 例如,我不明白事件是如何生成的。我完全迷路了,我知道 Tick 被定义为一个事件,但是 Tick 的事件描述是什么?我在哪里定义什么是 Tick?

  3. Tick 值在哪里被初始化。似乎我看过的所有示例都从未初始化事件,并且在附加示例中具有与语句类似的语句: If (Tick ! =null) 但并不明显 Tick 的初始化位置。我环顾四周,我找不到任何答案。
    在此先感谢您的帮助

4

2 回答 2

4
  1. 不,事件只是代表的一种特殊用途。你不能有一个没有委托的事件(尽管你可以有一个没有事件的委托 - 阅读委托以获取更多信息)。

  2. 不太确定我在这里理解你的问题。事件的描述将在文档中。仅查看代码,您就知道该对象上有一个名为 Tick 的事件,您可以将事件处理程序附加到该事件。

  3. 当您将事件处理程序添加到 Tick 时(即+=您看到的行),它将变为非空。这就是这些!= null检查正在做的事情——确保有人参与了该事件。

于 2013-07-23T15:37:20.940 回答
2

事件只是添加方法和删除方法的组合,两者都采用相同委托类型的单个参数。事件对传入委托的作用完全取决于实现。

Add处理程序中收到的事件委托最常见的事情是Delegate.Combine使用先前添加的委托(如果有),但也有一些其他可能性:

如果一个对象将支持多种事件,但许多实例的大多数订阅者为零,则可以将委托添加到表中。许多 WinForms 事件都是这样做的。

如果希望允许订阅者使用逆变委托类型,可以将接收到的委托放入List<>委托或持有委托对象的数组、链表中。

如果事件表示某些类型的对象会触发,但特定实例永远不会触发,则事件可能会简单地丢弃委托。例如,考虑一个ObservableFoo具有抽象更改通知事件的抽象类,以及一个约定,只要实例的属性发生更改,它将调用所有传入的委托;从它派生的ImmutableFoo类可以接受订阅请求,但由于它永远不会改变,所以它永远不必调用传入的委托(或对它们做任何其他事情)并且可以简单地丢弃它们。

由于事件是一对以委托类型作为参数的方法,因此每个事件都必须“根据定义”使用委托作为其参数类型。所有重要的事件都必须以某种形式存储传入的委托。接受多个订阅的最常见方法是将它们组合成一个多播委托(我不喜欢这种设计,顺便说一句,但这是最常见的);可以使用其他方法,但是要使用传入委托的事件必须以某种方式存储它们。

顺便说一句,在 C# 中声明事件有两种方法:一种可以显式提供添加/删除处理程序,在这种情况下,编译器将使用这些处理程序创建一个事件。也可以只提供事件名称和委托类型,在这种情况下,编译器将创建一个具有指定名称和范围的事件,一个具有相同名称和适当委托类型的私有变量,以及添加/删除的线程安全方法或从指示的变量中删除事件。表单eventName += something;eventName -= something;将作为对“添加”或“删除”方法的调用处理的语句;该名称的所有其他用途将指代委托人。请注意,在旧版本的 C# 中,在类中使用 and 将eventName += something;使用andeventName -= something;+=-=委托上的操作不是线程安全的,但较新的版本已经改变了这种行为。

于 2013-07-23T15:47:48.603 回答