2016-01-04 29 views
10

想要發佈這個,儘管我在寫這個問題時已經想清楚了。將在下面發佈答案。代碼分析警告CA2213 - IDisposable支持字段上的調用Dispose()

掌握VS代碼分析如下警告:

警告CA2213 'DBConn' 包含字段 'DBConn.k__BackingField' 這是IDisposable的類型: 'SqlConnection的'。更改'DBConn'上的Dispose方法以在此字段上調用Dispose或Close。

但是我的代碼確實是對DBConn屬性調用Dispose()。它不在背景上嗎?我有這樣的其他實例 - 我在哪裏處置編譯器不會拋出此警告的地方。這是下面的代碼:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Data.SqlClient;  

namespace TheProgramSpace 
{ 
    public sealed class DBConn : IDisposable 
    { 
     // class containing the database and its connection 
     public SqlConnection TheConn { get; } 
     public string DbPath { get; } 
     public string DbName { get; } 


     public DBConn(ProgInstance FPI) 
     { 
      // constructs new SQLConnection    
      DbPath = FPI.dbPath; 
      DbName = FPI.dbName; 

      string connString = "Data Source = " + DbPath + "; Initial Catalog =" + DbName + "; Integrated Security = True; " 
       + "Connect Timeout = 30; Encrypt = False; TrustServerCertificate = False; " 
       + "ApplicationIntent = ReadWrite; MultiSubnetFailover = False";      

      TheConn = new SqlConnection(connString); 

     } 

     public void Dispose() 
     {    
      TheConn.Dispose();    
     } 
    } 
} 
+0

您使用的是什麼版本的C#?在C#6之前,您會收到_different_編譯器警告,因爲您必須爲自動屬性提供setter。 –

+2

這是[已知錯誤](https://connect.microsoft.com/VisualStudio/feedback/details/1798055/code-analysis-rule-ca2213-disposablefieldsshoughtbedisposed-doesnt-understand-read-only-auto-properties-being在FxCop中,將在未來版本中修復)。 –

回答

9

代碼沒有問題。 Dispose在底層支持字段上調用。這是FxCop中的一個known bug,其中引入了C#6中引入的「getter-only」自動屬性。現在,您可以在類上使用suppress the warning,或者直接在FxCop中修改該屬性。

10

的原因是TheConn,因爲它沒有一個set訪問,是隻讀的。更改財產聲明爲

public SqlConnection TheConn { get; private set; } 

解決了這個問題。奇怪的是編譯器實際上並沒有把它作爲錯誤拋出;即,如果它無法運行,我應該無法在構造函數之外調用Dispose()方法。

+0

「我不應該在構造函數之外調用Dispose()方法」這是什麼意思? –

+0

@DStanley:我的意思是 - 當'TheConn'爲只讀時,爲什麼編譯器允許我根據Dispose()'方法調用'TheConn.Dispose()',如果它實際上不能處理對象? – dashnick

+0

因爲_reference_是隻讀的,不是實例。您可以調用方法(如'Dispose')並更改對象的屬性,但不能更改該屬性指向的實例。 –

相關問題