我的class级应该订阅自己的公共活动吗?
我正在使用C#3.0。 遵循标准事件模式我有:
public event EventHandler SomeEventHappens; protected virtual void OnSomeEventHappens(EventArgs e) { if (SomeEventHappens != null) { SomeEventHappens(this, e); } } private object _someProperty; public object SomeProperty { get { return _someProperty; } private set { if (_someProperty == value) { return; } OnSomeEventHappens(EventArgs.Empty); _someProperty = value; } }
在同一个class级中,我想在SomeProperty
改变时采取一些行动。 我看到它的方式我有3种选择:
1)在SomeProperty
setter中做东西。 因为我试图订阅所有事情的理念应该做一件事并做得好,因此有些事情让我误以为然。 将东西塞入制定者似乎与此相反,或至少具有倾向。
2)在OnSomeEventHappens
做一些OnSomeEventHappens
。 再次,似乎有点反对保持这个简单的部分。 此外,如果此方法被覆盖,如果实现者不调用基本方法,则可能会丢失function。
3)让class级订阅SomeEventHappens
。 对我来说,就封装而言,这似乎是正确的选择,而且看起来很干净。 同样,如果覆盖了OnSomeEventHappens
,可能会产生影响。
也许有更优雅的东西? 我不能在选项2和3之间做出决定,我很好奇最佳实践是什么。 也许最安全的地方就是物业安置者。
思考?
更新:感谢下面的精彩评论和答案。 我已经知道让一个类订阅自己的事件是“没关系”,尽管在我的情况下我倾向于不做因为开销。 我已经考虑了我的虚拟方法的潜在重写器的行为以及我想要发生什么。
在我的实际案例中,我真的不希望在没有设置属性的情况下引发事件。 由于下面的答案指导了我的思考过程,我认为我可以选择1,因为开销较低,inheritance人不正当行为的风险降低,而且通常对我来说更有意义。 再次感谢!
如果从某个公共位置(属性过程或其他函数)调用SomeEventHappens和OnSomeEventHappens,那么您不必担心忽略引发事件的覆盖器。 我宁愿重写函数而不是处理事件,因为开销较少。
在.NET之外的对象框架中,订阅自己的事件的对象主要是因为这样的事情导致循环引用可以使对象无限期地存活。 这在.NET中不是一个问题,但对于我来说这个对象以自己的方式进行摸索似乎仍然“奇怪”。
如果一个类总是需要知道属性何时发生变化,那么最好的办法是将OnSomeEventHappens方法设置为虚拟,并在需要附加信息的后代类中覆盖它。 将代码放入事件触发方法中是可以的。 事件发射方法正是因为每个想要发射该事件的人都有统一的方法来执行它。
如果您偶尔需要通知房产何时发生变化,那么我认为订阅和取消订阅该活动是合适的。
您是否总是想要采取此行动,或者您是否想要订阅和取消订阅? 在后一种情况下,选项3显然是个好主意。
您希望采取的行动是另一个class级可能希望采取的行动吗? 再次,这将倾向于选项3。
您希望采取的行动本身是设置财产的一部分吗? 如果是这样,可能建议采取行动1。
选项3对我来说听起来像一个很好的“轻触”方法。
如果您拥有自己对象的状态,那么捕捉事件对我来说听起来不对。 我会选择一个单独的虚拟方法。 不要干涉你的活动,并希望孩子们扔掉它。 也许这看起来像:
private object _someProperty; public object SomeProperty { get { return _someProperty; } private set { if (_someProperty != value) { OnSettingSomeProperty(_someProperty, value); OnSomeEventHappens(EventArgs.Empty); _someProperty = value; } } } protected virtual void OnSettingSomeProperty(object oldValue, object newValue) { // children can play here, validate and throw, etc. }