2010-10-12 50 views
0

我有下面的代碼: 包含兩個一次性成員的一次性類。 其中之一是使用new()方法進行初始化,另一個使用靜態工廠方法。 我也有靜態代碼分析規則,CA2213作爲錯誤。FxCop的CA2213錯誤在VS2010

public class DisposableClass : IDisposable 
{ 
    private WebClient m_DisposableMember1; 

    public WebClient DisposableMember1 
    { 
     get 
     { 
      if (m_DisposableMember1 == null) 
      { 
       m_DisposableMember1 = new WebClient(); 
      } 
      return m_DisposableMember1; 
     } 
    } 

    private WebClient m_DisposableMember2; 

    public WebClient DisposableMember2 
    { 
     get 
     { 
      if (m_DisposableMember2 == null) 
      { 
       m_DisposableMember2 = Factory.Create(); 
      } 
      return m_DisposableMember2; 
     } 
    } 


    #region Finalize/Dispose Pattern 
    private bool m_IsDisposed = false; 

    //Implement IDisposable. 
    public void Dispose() 
    { 
     Dispose(true); 
     GC.SuppressFinalize(this); 
    } 

    ~DisposableClass() 
    { 
     Dispose(false); 
    } 

    protected virtual void Dispose(bool disposing) 
    { 
     if (!m_IsDisposed) 
     { 
      if (disposing) 
      { 
       DisposableMember1.Dispose(); 
       // DisposableMember2 in not disposed and not notified by fxCop 
      } 

      m_IsDisposed = true; 
     } 
    } 
    #endregion Finalize/Dispose Pattern 

} 

這是一個簡單的工廠類:

public static class Factory 
{ 
    public static WebClient Create() 
    { 
     return new WebClient(); 
    } 
} 

當我致電DisposableMember1屬性的Dispose()方法,我得到CA2213。 當我調用m_DisposableMember1成員的Dispose()方法時,我不會收到此錯誤。

更多了,我沒有得到這個錯誤m_DisposableMember2(至極是使用靜態工廠初始化),並且它沒有被配置。

有沒有人熟悉這個問題?什麼會導致這種行爲?

回答

2

CA2213沒有特別侵蝕性有關識別應該被設置的字段。在其他潛在問題中,它只考慮從構造函數調用中直接分配的字段。通過屬性或構造函數調用以外的來源賦值字段值不會導致目標字段被規則包含在「應該丟棄」字段的池中。

1

您期待有點太離譜了這個工具的智慧的。該屬性是該領域的別名,僅對人眼而言是顯而易見的。它需要非常複雜的分析才能讓工具看到。 FxCop沒有那種馬力。你的代碼實際上是可疑的。如果該屬性從未被客戶端代碼使用,那麼您將創建WebClient對象並立即處置它。改用該字段,測試null和Dispose()。

與第二場的問題可能是由需要,以避免不必要的警告工具引起的。它只會抱怨,如果它可以絕對肯定地確定該字段已經初始化。在這裏同樣缺乏智慧,它不能說工廠總是返回一個非空引用。只有當它看到類中使用的構造函數本身時,才能確定該字段需要處理。

這是一個很好的工具,而不是完美的。