2016-01-04 24 views
10

Chciałbym to opublikować, mimo że doszedłem do tego, kiedy pisałem to pytanie. Odpisze odpowiedź poniżej.Analizy kodów Ostrzeżenie CA2213 - Call Dispose() na IDisposable backing field

Pierwsze następujące ostrzeżenie z VS Analiza kodu:

Ostrzeżenie CA2213 'DBConn' zawiera pole 'DBConn.k__BackingField', który jest typu IDisposable: 'SqlConnection'. Zmień metodę Dispose na "DBConn", aby wywołać Dispose lub Close w tym polu.

Ale mój kod robi wywołania Dispose() na nieruchomości DBConn. Czy to nie na polu zaplecza? Mam inne tego typu sytuacje - gdzie pozbywam się miejsca, w którym kompilator nie wyświetla tego ostrzeżenia. Jest to poniższy kod:

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

Jaką wersję C# używasz? Przed C# 6 otrzymasz ostrzeżenie o innym znaku kompilacji, ponieważ musisz dostarczyć narzędzie ustawiające dla właściwości automatycznych. –

+2

To jest [znany błąd] (https://connect.microsoft.com/VisualStudio/feedback/details/1798055/code-analysis-rule-ca2213-disposablefieldsdostosowano -odsynchronizuj--zwykle-automatyczne-używanie -disposed) w FxCop, który zostanie naprawiony w przyszłej wersji. –

Odpowiedz

9

Nie ma problemu z Twoim kodem. Disposebędzie będzie wywoływane na ukrytym polu podkładu. Jest to known bug w FxCop, który pojawił się wraz z wprowadzeniem automatycznych właściwości "getter-only", które zostały wprowadzone w C# 6. Na razie możesz albo suppress the warning z atrybutem na klasie, albo po prostu zignorować go, dopóki nie zostanie naprawiony w FxCop.

10

Powodem jest to, że TheConn, ponieważ nie mają set akcesor, został tylko do odczytu. Zmiana deklaracji właściwości na

public SqlConnection TheConn { get; private set; } 

rozwiązała problem. Dziwne jest to, że kompilator nie rzuca tego jako błąd; tj. nie powinienem był w ogóle wywoływać metody Dispose() poza konstruktorem, jeśli nie był on w stanie uruchomić.

+0

"Nie powinienem był w ogóle wywoływać metody Dispose() poza konstruktorem" co przez to rozumiesz? –

+0

@DStanley: Mam na myśli - kiedy 'TheConn' był tylko do odczytu, dlaczego kompilator pozwolił mi wywołać' TheConn.Dispose() 'z metody' Dispose() ', jeśli w rzeczywistości nie był w stanie pozbyć się przedmiotu? – dashnick

+0

Ponieważ _reference_ jest tylko do odczytu, a nie instancja. Możesz wywoływać metody (jak "Dispose") i zmieniać właściwości obiektu, ale nie możesz zmienić, do której instancji jest przypisana właściwość. –