我是C#活动和代表的初学者。如果你看一下the URL I have used to learn about events,几乎没有什么问题可以解决。
我可以在没有与之关联的代理的情况下举办活动吗?我发现的exmaples总是把它们放在一起。
例如,我不明白如何生成事件。我完全迷失了,我知道Tick被定义为一个事件,但Tick的事件描述是什么?我在哪里定义什么构成Tick?
此外,Tick值会在哪里初始化。似乎我所看到的所有示例都没有初始化事件,并且对语句有一个类似的声明:If(Tick!= null)在附加的示例中,但它不是obviuos,其中Tick是初始化的。我环顾四周,我找不到任何答案 在此先感谢您的帮助
答案 0 :(得分:4)
不,事件只是代表的特殊用途。如果没有代表,您就不能拥有一个活动(尽管您可以拥有一个没有活动的代表 - 请阅读delegates以获取更多信息)。
我不确定我在这里理解你的问题。事件的描述将在文档中。单独查看代码,您只知道该对象上有一个名为Tick的事件,您可以将事件处理程序附加到。
当您向Tick添加事件处理程序(即您看到的+=
行)时,它将变为非null。这就是那些!= null
检查所做的事情 - 确保某人已附加到该事件上。
答案 1 :(得分:2)
事件只是add方法和remove方法的组合,两者都采用相同委托类型的单个参数。事件对传入的委托的作用完全取决于实现。
在Add
处理程序中收到的事件委托最常见的事情是Delegate.Combine
与之前添加的委托(如果有的话),但还有其他一些可能性:
如果一个对象支持多种事件,但许多实例的大多数事件都没有订阅者,那么可以将该委托添加到表中。许多WinForms事件都是这样做的。
如果想要允许订阅者使用逆变委托类型,可以将收到的委托放入数组,List<>
,链表,委托或委托持有对象。
如果事件表示某些类型的对象将触发,但特定实例永远不会触发,则事件可能只是丢弃该委托。例如,考虑一个带有抽象变更通知事件的抽象ObservableFoo
类,以及一个合同,该变量表示实例的属性改变它将调用所有传入的委托将被调用;从它派生的ImmutableFoo
类可以接受订阅请求,但由于它永远不会改变,因此它永远不必调用传入的代理(或对它们执行任何其他操作)并且可以简单地丢弃它们。
由于事件是一对将委托类型作为参数的方法,因此每个事件必须“按定义”使用委托作为其参数类型。所有非平凡的事件必须以某种形式存储传入的委托。接受多个订阅的最常见方式是将它们组合成一个多播委托(我不喜欢设计,顺便说一句,但它是最常见的);可以采用其他方法,但是要使用传入代理的事件必须以某种方式存储它们。
顺便说一句,有两种方法可以在C#中声明一个事件:一个可以显式提供添加/删除处理程序,在这种情况下,编译器将使用这些处理程序创建一个事件。也可以只提供事件名称和委托类型,在这种情况下,编译器将创建具有指定名称和范围的事件,具有相同名称的私有变量 和适当的委托类型,以及线程 - 安全添加/删除方法,用于从指示的变量添加或删除事件。表单eventName += something;
或eventName -= something;
的语句将作为对“添加”或“删除”方法的调用进行处理;名称的所有其他用途将引用代表。请注意,在旧版本的C#中,将使用委托上的eventName += something;
和eventName -= something;
操作处理类中的+=
和-=
,这些操作不是线程安全的,但较新的版本改变了这种行为。