2012-08-16 77 views
17

更新:当代码分析选项“禁止生成的代码的结果(仅限管理)”关闭,并且规则集设置为“Microsoft基本设计指南规则”时,会发生这种情况。为什么空委托事件处理程序会导致CA1061警告?

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

Link to MS Connect item

我们经常初始化事件处理程序有一个空的委托,以避免检查空值的需要。例如: -

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

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

而且,我发现,这似乎当在基本类型的事件处理程序都发生:

  • 比在基类和两个事件处理或事件处理程序 - 和 -
  • 事件等代表派生类将使用匿名方法或空委托(内联或构造函数)进行初始化。

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

+0

您是否正在初始化您的EventHandlers以避免在启动之前对它们进行空检查? – 2012-08-16 19:40:36

+0

这是主要原因,是的。 – Sean 2012-08-16 19:54:35

+0

它在我看来是VS 2012的一个怪癖。如果你覆盖了基类中的委托,我可能会看到它,但就目前而言,它看起来完全不符合CA1061的描述:http ://msdn.microsoft.com/en-us/library/ms182143.aspx – 2012-08-16 20:34:47

回答

4

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

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

不幸的是,C#编译器在决定如何命名子类的自动生成的“东西”时,不包含父类的“自动生成的东西”的某种记录。在ILDasm中打开这个问题,问题就会变得很明显。很高兴知道您找到了解决办法。这个警告完全可以忽略,因为你不能接触来自C#的静态委托,这要感谢非C#兼容的命名。

+1

对于正在发生的事情而言,这当然是一个合理的解释,但没有解决为什么它只是从最新版本的Visual Studio开始。不过,在上周的2012年代码分析中,我发现了很多其他的怪事,所有关于事件处理程序和LINQ查询的匿名方法,所以感谢您的洞察力。 – Sean 2012-08-25 00:41:00

相关问题