2016-01-04 88 views
10

私は質問を書いていたときにそれを理解しましたが、これを投稿したいと思いました。以下の回答を投稿します。コード分析警告CA2213 - IDisposableバッキングフィールドにDispose()を呼び出してください

VSコード分析と次の警告行き方: 'SqlConnectionオブジェクト':CA2213 'DBConn' を警告

IDisposableを型であるフィールド 'DBConn.k__BackingField' を含んでいます。このフィールドでDisposeまたはCloseを呼び出すには、 'DBConn'のDisposeメソッドを変更します。

しかし、私のコードは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_コンパイラの警告は、自動プロパティ用のセッターを提供する必要があるため、得られるはずです。 –

+2

これは[既知のバグ](https://connect.microsoft.com/VisualStudio/feedback/details/1798055/code-analysis-rule-ca2213-disposablefieldsshouldbedisposed-doesnt-understand-read-only-auto-properties-being)です。 FxCopでは将来のリリースで修正される予定です)。 –

答えて

9

コードに問題はありません。 Disposeは、基底のバッキングフィールドで呼び出されます。これはFxCopのknown bugで、C#6で導入された「ゲッターのみ」の自動プロパティの導入によって浮上しました。今のところ、クラスの属性を持つsuppress the warningか、FxCopで修正されるまで無視されます。

10

理由はTheConn、それはsetアクセサを持っていなかったために、読み取り専用だったということです。これは以下のコードです。プロパティ宣言を

に変更すると、
public SqlConnection TheConn { get; private set; } 

が解決されました。奇妙なことは、コンパイラは実際にはこれをエラーとして投げないということです。つまり、実行できなかった場合は、コンストラクタの外でDispose()メソッドを呼び出すことはできません。

+0

"コンストラクタの外でDispose()メソッドを呼び出すことはできません。"これはどういう意味ですか? –

+0

@DStanley: 'TheConn'が読み込み専用だったとき、コンパイラは' TheConn.Dispose() 'を' Dispose() 'メソッドから呼び出すことをなぜ許可しましたか?オブジェクトを処分するか? – dashnick

+0

_reference_は読み取り専用であり、インスタンスではないためです。メソッド( 'Dispose'など)を呼び出してオブジェクトのプロパティを変更することはできますが、プロパティが指すインスタンスを変更することはできません。 –

関連する問題