2012-08-16 40 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

相關問題