17

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

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

链接到 MS Connect 项目

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

public EventHandler SomeEvent = delegate {};

但是,自从开始在 Visual Studio 2012 (RTM) 中编译我们的一些代码后,我注意到派生类中的许多事件现在正在触发CA1601:不要在 Visual Studio 2012 的代码分析中隐藏基类方法警告。

这是一个将触发警告的示例:

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

附录:我发现代码分析中“Suppress results from generated code”选项被关闭了。

此外,我发现这似乎发生在基类型中的事件处理程序是两者时:

  • EventHandler 或 EventHandler 以外的委托 - 并且 -
  • 基类和派生类中的事件都使用匿名方法或空委托(内联或构造函数)初始化。

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

4

1 回答 1

4

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

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

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

于 2012-08-24T23:10:20.880 回答