Quello che stai facendo è come C++ e RAII. E in C#, è all'incirca come quello che si può ottenere con l'idioma C++/RAII.
Eric Lippert, che conosce qualcosa su C#, è categoricamente contrario all'uso di IDispose e all'utilizzo di istruzioni come idioma C# RAII. Vedi la sua risposta in profondità qui, Is it abusive to use IDisposable and "using" as a means for getting "scoped behavior" for exception safety?.
Parte del problema con IDisposable utilizzato in questo modo RAII è che IDisposable ha requisiti molto rigorosi da utilizzare correttamente. Quasi tutto il codice C# che ho visto utilizza IDisposable non riesce a implementare correttamente il pattern. Joe Duffy ha creato un post sul blog che fornisce dettagli meticolosi sul modo corretto di implementare il modello IDisposable http://joeduffyblog.com/2005/04/08/dg-update-dispose-finalization-and-resource-management/. Le informazioni di Joe sono molto più dettagliate e complete di quanto menzionato su MSDN. Joe conosce anche qualcosa su C#, e ci sono stati molti contributori molto intelligenti che hanno aiutato a concretizzare quel documento.
Le cose semplici possono essere fatte per implementare il modello minimale IDSposable (per uso come in RAII), ad esempio sigillare la classe, e poiché non ci sono risorse non gestite che non hanno un finalizzatore e così via. MSDN https://msdn.microsoft.com/en-us/library/system.objectdisposedexception%28v=vs.110%29.aspx è una bella panoramica, ma le informazioni di Joe hanno tutti i dettagli cruenti.
Ma l'unica cosa che non si può evitare con IDisposable è la sua natura "virale". Le classi che tengono conto di un membro che è identificabile devono diventare IDisposable ... non un problema nello scenario using(RAII raii = Pool.GetRAII())
, ma qualcosa su cui prestare molta attenzione.
Tutto ciò detto, nonostante la posizione di Eric (di cui tendo ad essere d'accordo con lui su quasi tutto il resto), e il saggio di 50 pagine di Joe su come implementare correttamente lo schema IDisposable ... Lo uso come C#/RAII idiom me stesso.
Ora solo se C# aveva 1) i riferimenti non annullabili (come il C++ o D o SpeC#) e 2), i tipi di dati a fondo immutabili (come D, o anche F # [ si può fare il # tipo F di immutabile in C# , ma è un sacco di boilerplate, ed è semplicemente troppo difficile per avere ragione ...rende semplice , e il duro impossibile]) e 3) design per contratto come parte della lingua propriamente detta (come D o Eiffel o SpeC#, non come l'abominio dei codici C#). sigh Forse C# 7.
fonte
2015-06-10 13:26:35
Chiamare Dispose() è * sempre * opzionale. Cosa succederà quando il programma client non lo chiama? Difficile vedere che non "spingere" qualcosa suona male. Il finalizzatore è il backup di Dispose() non utilizzato, in nessun modo è possibile chiamare ReleaseResource() in un finalizzatore. –