2011-07-31 69 views
3

我在我的項目上運行完整的代碼分析,它說它有500個問題。我已經把它煮成了300個,但我正在爲一個我似乎無法找到解決方案的問題而苦苦掙扎。在這種情況下解析代碼分析「CA2000」規則?

規則CA2000狀態:

如果一次性對象不明確的所有引用之前,它是超出範圍設置,對象會在某個不確定的時間被設置在垃圾收集器運行的終結物體。由於可能發生的異常事件會阻止對象的終結器運行,因此應該明確處理該對象。

有關規則的更多信息,請參見上面鏈接的頁面。

該規則失敗上的代碼是這樣的:

internal Window(Game game, Control parent, string title, bool visible) 
    : base(game, parent, visible, new ScreenspaceRectangle(game, Color.Black, Vector.Zero, Vector.Zero)) 
{ 
} 

和描述是:

CA2000:Microsoft.Reliability:在方法「Window.Window(遊戲,控制字符串,布爾)',調用System.IDisposable.Dispose對象'新的ScreenspaceRectangle(遊戲,Color.Black,Vector.Zero,Vector.Zero)'之前,所有引用超出範圍。

我知道這個問題可以通過在創建對象周圍使用「using」聲明來正常解決,以確保它始終正確處置。但是在這種情況下我怎麼解決它?

+1

爲什麼ScreenspaceRectangle需要放置? – 2011-07-31 06:52:55

回答

3

假設Window類是自定義類,你應該確保基類的構造函數存儲ScreenspaceRectangle的參考,如果它需要它的構造函數外,它實現IDisposable並配置ScreenspaceRectangle的實例在Dispose方法。

否則,請確保該對象正在被放置在基類構造函數中。

1

c#/ vb.net的一個令人討厭的限制是它們不允許將鏈式構造函數或字段初始值設定項封裝在try-catch或try-finally塊中。如果創建對象Foo需要創建Foo將負責處理的其他一些IDisposable對象,則可能難以確保如果從Foo,其子類型或其構造函數的構造函數中拋出異常超類型。我知道處理這個問題的最簡潔的方法是使用一個受保護的構造函數,它包裝在工廠方法中,它將創建一個「一次性管理器」實例並將其傳遞給構造器鏈。任何可以創建IDisposable的東西都應該添加到一次性管理器中;如果構造函數拋出異常,則一次性管理器將刪除所有已註冊的一次性項目。

這種方法的一個優點是它允許通過創建它們的代碼處理嵌套IDisposables的清理,從而最小化對象創建和清理代碼不同步的危險。一個警告是,必須使用線程靜態字段來跟蹤一次性管理器,或者將其傳遞給構造器鏈的每一步。前一種方法感覺很糟糕,但具有允許字段初始化器安全地創建IDisposable對象的優點。