2013-03-01 7 views
6

Es ist nicht so wichtig, aber ich versuche herauszufinden, was es mir sagt, und ist es eine legitime Warnung? Kann mir jemand diesen Fehler in einfachen Worten erklären?CA1001 Visual Studio 2012 Code Analyse Warnung. Was heißt das?

CA1001 Typen, die Wegwerf-Felder besitzen sollte

implementieren IDisposable auf 'MemVoteManager' Einweg sein, weil sie Mitglieder der folgenden IDisposable Typen erstellt: 'CongressDBEntities'. Wenn 'MemVoteManager' zuvor versandt wurde, wird das Hinzufügen neuer Mitglieder, die IDisposable zu diesem Typ implementieren, als eine Änderung der bestehenden Verbraucher angesehen.

public class MemVoteManager : AbstractDataManager, IMemVoteManager 
{ 
    private CongressDBEntities context = new CongressDBEntities(); 

    public int AddMemVote(tMemVoteScore mvs) 
    { 
     //Insert Model 
     context.tMemVoteScores.Add(mvs); 
     context.SaveChanges(); 

     int newPK = mvs.MemVoteScoresID; 

     //Update funky column ID with PK as well 
     var memVoteItem = (from m in context.tMemVoteScores 
          where m.MemVoteScoresID == newPK 
          select m).SingleOrDefault(); 

     memVoteItem.ID = memVoteItem.MemVoteScoresID; 
     context.SaveChanges(); 
     return newPK; 
    } 
+3

Es wird schwierig zu erklären, was diese Warnung Ihnen sagt, ohne dass Sie nur die Warnung wiederholen müssen. Da Ihr Typ ein Feld hat, in dem er ein Objekt erstellt und speichert, in dem das Objekt IDisposable implementiert, sollten Sie IDisposable auch für Ihren Typ implementieren, indem Sie das Objekt in diesem Feld entsorgen. Das ist im Grunde, was die Warnung sagt. Der Bruchteil der Änderung besteht darin, dass jeder existierende Code, der Ihren Typ verwendet, nicht mit "Dispose" erstellt wurde und somit eine brechende Änderung ist. –

Antwort

7

Sie implementieren könnte IDisposable so der Kontext entsorgt werden von wenn die Konsumenten mit Ihrer Klasse fertig sind, aber Sie könnten besser dran sein, wenn der Kontext kein Mitglied der Klasse ist. schaffen es nur, wenn Sie es brauchen und entsorgen Sie es, wenn Sie fertig sind:

public int AddMemVote(tMemVoteScore mvs) 
{ 
    //Insert Model 
    using(CongressDBEntities context = new CongressDBEntities()) 
    { 
     context.tMemVoteScores.Add(mvs); 
     context.SaveChanges(); 

     int newPK = mvs.MemVoteScoresID; 

     //Update funky column ID with PK as well 
     var memVoteItem = (from m in context.tMemVoteScores 
          where m.MemVoteScoresID == newPK 
          select m).SingleOrDefault(); 

     memVoteItem.ID = memVoteItem.MemVoteScoresID; 
     context.SaveChanges(); 
    } 
    return newPK; 
} 

Contexts leicht sind so sie jedes Mal für die Erstellung nicht eine große Strafe gibt. Außerdem müssen Sie sich keine Sorgen darüber machen, dass Verbraucher Sie darüber informieren, den Kontext zu entfernen, und Sie haben nicht viel aufgebaute Änderungen im Speicher, wenn eine Instanz der Klasse mehrmals verwendet wird.

+0

Aber ich dachte, dass alles schließlich Müll gesammelt wurde, nachdem es außer Reichweite geriet?Aber gehen Sie weiter und wickeln Sie es wie Sie oben getan haben, wenn das macht Code-Analyse glücklich – punkouter

+1

@punkouter, das Problem mit diesem Gedanken Prozess ist, dass es eine Reihe von Möglichkeiten Objekte *** *** *** erreicht Garbage Collection. Speicherverwaltung, obwohl es in .NET automatisiert ist, ist nicht gedankenlos. Betrachten Sie eine Klasse, die einen Verweis auf eine andere Klasse enthält, auf die auch ein Objekt verweist, das für immer existiert. Ich weiß, es scheint wie ein Randfall - aber es ist nicht. *** Keines dieser Objekte *** wird Müll gesammelt, bis die Anwendung heruntergefahren wird. –

+0

Ok. Die Implementierung von I Disposable und das Aufrufen ist eine Möglichkeit, sicher zu sein, dass die Klasse Müll gesammelt wird ... Vielleicht wird sie jetzt nicht benötigt, aber es ist die beste Praxis, sie immer nur im Fall – punkouter

3

Es lassen Sie dieses Feld wissen context Einweg Elemente enthält. Das bedeutet, dass diese Mitglieder Dispose() aufgerufen haben müssen, damit Garbage Collection stattfinden kann. Daher möchte er, dass Sie die Schnittstelle IDisposable unter MemVoteManager implementieren, so dass Sie Dispose() auf den Kontext und/oder seine Mitglieder, die Disposable sind, aufrufen können.

So Sie Code als solche ändern:

public class MemVoteManager : AbstractDataManager, IMemVoteManager, IDisposable 

und implementieren dann die Mitglieder der IDisposable Schnittstelle wie folgt aus:

public void Dispose() 
{ 
    // call dispose on the context and any of its members here 
} 
+0

Also jede Klasse innerhalb meiner Klasse, die Idisposable implementiert, bedeutet, dass ich auch iDisposable implementieren? Ohne es kann ich ein Speicherleck erstellen? Wie ich oben erwähnt habe, ist alles Müll gesammelt. – punkouter

+0

@punkouter, wenn die Klasse 'IDisposable' implementiert, bedeutet dies explizit, dass sie nicht verwaltete Ressource loswerden muss. Eine Datenbankverbindung zum Beispiel *** (die tatsächliche Verbindung) *** - das ist eine nicht verwaltete Ressource. Da Sie also ein Kontextobjekt haben, das andere Objekte enthält, die schließlich zu nicht verwalteten Ressourcen führen, müssen Sie sicherstellen, dass Sie "Dispose()" aufrufen. –

+0

aber das Umschließen des DBcontext mit einem 'using' ist das gleiche wie das Implementieren eines idisposable? – punkouter