2013-03-01 8 views
6

Non è importante ma sto cercando di capire cosa mi sta dicendo ed è un avvertimento legittimo? Qualcuno può spiegare questo errore in termini semplici per me?Avviso di analisi del codice di Visual Studio 2012 CA1001. Cosa significa?

CA1001 tipi che possiedono campi monouso devono essere usa e getta

Implementare IDisposable su 'MemVoteManager' perché crea i membri dei seguenti tipi IDisposable: 'CongressDBEntities. Se "MemVoteManager" è stato precedentemente spedito, l'aggiunta di nuovi membri che implementano IDisposable a questo tipo è considerata una modifica irrisoria ai consumatori esistenti di .

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

Sarà difficile spiegare che cosa ti dice di avvertire senza dover semplicemente ripetere l'avviso. Poiché il tuo tipo ha un campo, dove costruisce un oggetto e lo memorizza, dove quell'oggetto implementa IDisposable, dovresti implementare IDisposable anche sul tuo tipo, eliminando l'oggetto in quel campo. Questo è fondamentalmente ciò che dice l'avvertimento. La parte del cambiamento sostanziale è che qualsiasi codice esistente che usi il tuo tipo non sarebbe stato costruito pensando a 'Dispose', e quindi è un cambiamento decisivo. –

risposta

7

Si potrebbe implementare IDisposable in modo che il contesto sarà smaltito quando i consumatori hanno finito con la tua classe, ma potresti stare meglio NON avere il contesto come membro della classe. Basta creare quando ne avete bisogno e smaltirlo quando hai finito:

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; 
} 

I contesti sono leggeri, quindi non c'è un enorme pena per la creazione di ogni volta. Inoltre, non devi preoccuparti dei consumatori che notificano di disporre del contesto e non hai molte modifiche incorporate in memoria se una istanza della classe viene utilizzata più volte.

+0

Ma pensavo che alla fine tutto sarebbe stato spazzato via dopo che era andato fuori uso?Ma mal fatto e avvolgilo come hai fatto sopra se questo renderà l'analisi del codice felice – punkouter

+1

@punkouter, il problema con quel processo di pensiero è che ci sono un certo numero di modi in cui oggetti *** mai *** raggiungono la garbage collection. La gestione della memoria, sebbene sia automatizzata in .NET, non è sconsiderata. Considera una classe che ha un riferimento a un'altra classe a cui fa riferimento anche un oggetto che vive per sempre. So che sembra un caso limite, ma non lo è. *** Nessuno di questi oggetti *** verrà raccolto automaticamente finché l'applicazione non viene arrestata. –

+0

Ok. Quindi implementare I Disposable e chiamarlo è un modo per essere sicuri che la classe sarà raccolta dei dati inutili ... Forse non è necessaria ora ma è comunque buona pratica implementarla sempre in ogni caso solo nel – punkouter

3

E 'ti permette di sapere che il campo context contiene componenti usa e getta. Ciò significa che questi membri devono avere Dispose() chiamato in modo che si possa verificare la Garbage Collection. Pertanto, desidera implementare l'interfaccia IDisposable su MemVoteManager in modo da poter chiamare Dispose() sul contesto e/o sui suoi membri che sono monouso.

Quindi modificare il vostro codice ed in quanto tale:

public class MemVoteManager : AbstractDataManager, IMemVoteManager, IDisposable 

e quindi implementare i membri dell'interfaccia IDisposable in questo modo:

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

Quindi qualsiasi classe all'interno della mia classe che implementa Idisposable significa che devo implementare anche iDisposable? Senza di esso posso creare una perdita di memoria? Come ho già detto sopra, anche se tutto è spazzatura raccolta ... il suo codice gestito! – punkouter

+0

@punkouter, se la classe implementa 'IDisposable' che significa esplicitamente che ha risorse non gestite per sbarazzarsi di. Una connessione al database per esempio *** (la connessione effettiva) *** - questa è una risorsa non gestita. Quindi, dal momento che si dispone di un oggetto di contesto, che ha altri oggetti che alla fine portano a risorse non gestite, è necessario ** assicurarsi ** che venga visualizzato 'Dispose()' su di essi. –

+0

ma il wrapping del DBcontext con un 'utilizzo' sarà lo stesso dell'implementazione di un identificativo? – punkouter

Problemi correlati