为什么空委托事件处理程序会导致CA1061警告?

时间:2012-08-16 19:29:34

标签: c# code-analysis visual-studio-2012 .net-4.5

更新:当代码分析选项“禁止生成代码的结果(仅限管理)”关闭,并且规则集设置为“Microsoft基本设计指南规则”时,会发生这种情况。

在2013-04-26,Microsoft确认这是一个错误,但不会在此版本或下一版本的Visual Studio中修复它。

Link to MS Connect item

我们经常使用空委托初始化事件处理程序,以避免检查空值。 E.g:

public EventHandler SomeEvent = delegate {};

但是,自从开始在Visual Studio 2012(RTM)中编译我们的一些代码以来,我注意到派生类中的很多事件现在都在Visual Studio 2012的代码分析中触发CA1601: Do not hide base class methods警告。

以下是一个会触发警告的示例:

using System;
using System.ComponentModel;

[assembly: CLSCompliant( true )]

namespace TestLibrary1
{
    public abstract class Class1
    {
        public event PropertyChangedEventHandler PropertyChanged = delegate {};
    }

    public class Class2 : Class1
    {
        // this will cause a CA1061 warning
        public event EventHandler SelectionCancelled = delegate { };
    }

    public class Class3 : Class1
    {
        // this will not cause a CA1061 warning
        public event EventHandler SelectionCancelled;
    }
}

注意:在VS2012中,在.NET 4.5或.NET 4.0中编译时会触发警告。相同的样本不会在VS2010中触发警告。

除了性能原因之外,是否有任何合理的理由我们不应该使用空委托来初始化事件?默认的假设是它可能只是Visual Studio 2012中分析的一个怪癖。

以下是那些无法访问VS2012的代码分析结果:

  

CA1061不要隐藏基类方法更改或删除“Class2.Class2()”因为它隐藏了一个更具体的基类方法:'Class1.Class1()'。 TestLibrary1 Class1.cs 14

附录:我发现代码分析中的“抑制生成代码的结果”选项已关闭。

另外,我发现当基类型中的事件处理程序都是:

时,似乎会发生这种情况
  • 除EventHandler或EventHandler以外的委托 - 和 -
  • 使用匿名方法或空委托(内联或构造函数)初始化
  • 基类和派生类中的事件。

可能的相关性:我们正在运行Visual Studio 2012 RTM,它已在候选版本上就地安装。

1 个答案:

答案 0 :(得分:4)

问题是C#编译器生成一个静态委托,用于初始化您的实例委托,Class1和Class2的名称相同。

存在

Class1.CS$<>9__CachedAnonymousMethodDelegate1以供Class1的构造函数初始化PropertyCancelled,而Class2.CS$<>9__CachedAnonymousMethodDelegate1_存在以供Class2的构造函数初始化SelectionCancelled

不幸的是,在决定如何为子类命名自动生成的“东西”时,C#编译器不包含父类“自动生成”东西的某种记录。在ILDasm中打开这个问题,问题就变得很明显了。很高兴知道你找到了解决方法。由于非C#兼容命名,因此无法触及C#中的静态委托,因此忽略该警告是完全合理的。