CA1070规则疑问:为何禁止将事件字段声明为virtual?
关于C#中virtual事件的矛盾疑问
.NET代码分析规则CA1070“不要将事件字段声明为virtual”的官方文档指出:
请勿在基类中声明virtual事件。派生类中重写的事件会出现未定义行为。C#编译器无法正确处理此情况,订阅派生类事件的订阅者实际是否订阅了基类事件是不可预测的。
这是怎么回事?
官方C#编程指南也用非常相似的措辞证实了这一点:
请勿在基类中声明virtual事件并在派生类中重写它们。C#编译器无法正确处理这些情况,订阅派生类事件的订阅者实际是否订阅了基类事件是不可预测的。
这是怎么回事?
另一方面:
针对event关键字的官方C#语言参考指出:
使用
virtual关键字将事件标记为virtual事件。派生类可以使用override关键字重写事件行为。更多信息,请参阅继承。[...]
官方C#语言规范针对事件指出:
virtual事件声明指定该事件的访问器是virtual的。
virtual修饰符适用于事件的两个访问器。
并且:
除了声明和调用语法的差异外,virtual、sealed、override和abstract访问器的行为与virtual、sealed、override和abstract方法完全相同。
在我看来,上述内容存在不可调和的矛盾:要么代码分析规则和编程指南有所隐瞒,要么语言规范和语言参考存在错误。那么实际情况究竟如何?
- 语言规范和参考是否是一厢情愿,描述了一个根本无法按所述实现的功能?
- 代码分析规则和编程指南是否是在试图保护开发者免受编译器bug的影响?
- 是否有人曾重现过代码分析规则和编程指南所警告的“未定义行为”、错误处理或不可预测性?
我对此十分好奇。
内容的提问来源于stack exchange,提问作者Mike Nakis
相关产品推荐
相关产品推荐

