事件与可覆盖的方法?

时间:2011-07-31 03:26:25

标签: c# events methods override

任何人都可以向我提供关于何时应该使用诸如“OnMyEvent”之类的可覆盖方法以及何时应该在C#中使用诸如“MyEvent”之类的事件的一般指导原则?

是否有可以定义使用内容的一般设计原则?

2 个答案:

答案 0 :(得分:7)

这两个功能模糊不清(两者都是为了进行某种形式的动态调度而设计),但不能直接比较。

事件是通知其他对象某个对象已经到某种state transition。它是一种体现the Observer Design Pattern的语言功能。这在许多情况下都很有用,但并不总是有用或可取的。这是完成特定工作的工具。

虚拟函数用于创建Object Oriented Polymorphism。它们几乎是每个设计模式的基本构建块,并且有很多面向对象的设计。

为了尝试比较它们,我假设你试图用任何一种功能实现某种形式的观察者模式。有了这个限制,仍然没有简单的规则可以决定你应该使用哪个。相反,你必须问自己这样的问题:

  • 是谁造成的:触发状态转换的操作会在内部发生,还是会在外部触发?

如果在内部触发,则可以使用事件或虚拟方法。如果从外部触发,则必须使用虚拟方法。

  • 谁在乎呢:定义状态的类应该处理状态转换的后果,还是外部类应该处理它?<​​/ li>

如果拥有该状态的类应该处理转换,那么它应该是一个虚方法。如果一个单独的类应该对转换做出反应,它应该是一个事件。

  • 我需要多少处理程序:您是否总是需要一个处理程序来响应状态转换,或者您需要多少处理程序?

如果您需要,可以接受使用虚拟方法或事件。如果你需要很多,那么使用一个事件将会容易得多。

  • 我是否知道在编译时我想要哪个处理程序:我是否绑定到一个众所周知的处理程序,还是绑定到未知的处理程序,可能会随着时间的推移而改变?

如果您需要更改处理程序,则必须使用事件。如果您只有一个在编译时已知的处理程序,则可以使用虚方法。

  • 我的代码应该如何耦合:您的处理程序代码是属于原始类型的派生类,还是属于其他地方?

如果它属于派生类,则需要虚拟方法。如果它属于其他地方,那么你需要一个事件。

如您所见,答案将在很大程度上取决于您的特定问题域和对象体系结构。好的设计不是通过一些检查清单神奇落入你的膝盖的东西。你必须考虑很多:)

修改

它可能无法直接应用于C#事件,但从现有工作中获取示例可能很有用。这是我刚刚发现的一篇简短的文章(在回答不同的问题时),关于Java中用于事件模式的设计备选方案:http://csis.pace.edu/~bergin/patterns/event.html

答案 1 :(得分:6)

当你有一个“有一个”时,事件是很好的,而在你有一个“是一个”关系的情况下,覆盖会好很多

例如,如果你有一个基类动物,很可能每只动物都有自己的移动方式。但是每只动物都会以某种方式想要移动。

现在想想一个可能“拥有”宠物的阶级人物。在这种情况下,人可能会对动物移动做出反应,但它实际上并不能处理动物移动。