任何人都可以向我提供关于何时应该使用诸如“OnMyEvent”之类的可覆盖方法以及何时应该在C#中使用诸如“MyEvent”之类的事件的一般指导原则?
是否有可以定义使用内容的一般设计原则?
答案 0 :(得分:7)
这两个功能模糊不清(两者都是为了进行某种形式的动态调度而设计),但不能直接比较。
事件是通知其他对象某个对象已经到某种state transition。它是一种体现the Observer Design Pattern的语言功能。这在许多情况下都很有用,但并不总是有用或可取的。这是完成特定工作的工具。
虚拟函数用于创建Object Oriented Polymorphism。它们几乎是每个设计模式的基本构建块,并且有很多面向对象的设计。
为了尝试比较它们,我假设你试图用任何一种功能实现某种形式的观察者模式。有了这个限制,仍然没有简单的规则可以决定你应该使用哪个。相反,你必须问自己这样的问题:
如果在内部触发,则可以使用事件或虚拟方法。如果从外部触发,则必须使用虚拟方法。
如果拥有该状态的类应该处理转换,那么它应该是一个虚方法。如果一个单独的类应该对转换做出反应,它应该是一个事件。
如果您需要,可以接受使用虚拟方法或事件。如果你需要很多,那么使用一个事件将会容易得多。
如果您需要更改处理程序,则必须使用事件。如果您只有一个在编译时已知的处理程序,则可以使用虚方法。
如果它属于派生类,则需要虚拟方法。如果它属于其他地方,那么你需要一个事件。
如您所见,答案将在很大程度上取决于您的特定问题域和对象体系结构。好的设计不是通过一些检查清单神奇落入你的膝盖的东西。你必须考虑很多:)
修改强>
它可能无法直接应用于C#事件,但从现有工作中获取示例可能很有用。这是我刚刚发现的一篇简短的文章(在回答不同的问题时),关于Java中用于事件模式的设计备选方案:http://csis.pace.edu/~bergin/patterns/event.html
答案 1 :(得分:6)
当你有一个“有一个”时,事件是很好的,而在你有一个“是一个”关系的情况下,覆盖会好很多
例如,如果你有一个基类动物,很可能每只动物都有自己的移动方式。但是每只动物都会以某种方式想要移动。
现在想想一个可能“拥有”宠物的阶级人物。在这种情况下,人可能会对动物移动做出反应,但它实际上并不能处理动物移动。