2009-04-17 1 views
5

Gli oggetti che derivano da HashAlgorithm come MD5CryptoServiceProvider hanno un metodo Dispose(), ma è privato. Invece ha un metodo Clear() che "Libera tutte le risorse" usato da esso..NET: eliminazione di un oggetto HashAlgorithm

WTF?

È questo come disporre correttamente di un HashAlgorithm, quindi?

var hasher = new MD5CryptoServiceProvider(); 

byte[] hashCode = hasher.ComputeHash(data); 

hasher.Clear(); 

Qualcuno vuole spiegarmelo? :)

+0

vi consiglio di utilizzare un altro algoritmo di hash anche se si può ben ritenere il Hash MD5 non sicuro in alcune applicazioni. Una buona alternativa sarebbe la famiglia SHA, come SHA 256. Sono disponibili anche per l'uso in .NET. – Skurmedel

+0

Buona chiamata. Ricordo che leggere MD5 si era rivelato vulnerabile qualche anno fa. Geeze, questo da Wikipedia: "Il 18 marzo 2006, Klima ha pubblicato un algoritmo [10] che può trovare una collisione in un minuto su un singolo computer portatile, usando un metodo che chiama tunneling." – core

risposta

3

Guardando con Reflector, il metodo Clear di HashAlgorithm chiama semplicemente il metodo privato Dispose. La ragione per esporre un metodo con il nome Clear era probabilmente solo che i progettisti della classe pensavano che sarebbe stato un nome più adatto per un algoritmo di hash. Si vedono stili simili all'interno di altre parti del BCL, ad esempio Close per System.IO.Stream. Inoltre, la procedura migliore è utilizzare un blocco using, che chiamerà automaticamente il metodo privato Dispose al termine.

+0

Come menzionato da altri, è meglio usare comunque un blocco 'using', che semplifica la logica try-finally/dispose per te ed è una pratica consigliata. – Noldorin

-4

Si dovrebbe lasciare che il GC gestisca quello per voi. Questo è il suo lavoro.

Alcune risorse devono essere eliminate, come le connessioni DB e gli handle di file, quindi inserirli in un blocco using (C#). Questo non è uno di quei casi, però.

+0

In realtà, HashAlgorithm (e quindi MD5CryptoServiceProvider) * do * implementa IDisposable, quindi dovrebbero essere disposti correttamente, chiamando il metodo Clear o con un blocco 'using'. – Noldorin

+3

Solo perché la classe implementa IDisposable, non significa che debba essere smaltito manualmente. A ciascuno il suo, però. –

+0

No, certo, ma il fatto che * * * implementi IDisposable significhi quasi sempre significa fortemente che dovrebbe essere disposto manualmente perché sta facendo un po 'di interoperabilità nativa all'interno. Il GC finirà per eliminarlo anche se non si richiama esplicitamente il metodo, ma l'ora in cui ciò si verifica non è garantita a breve. – Noldorin

10

Mentre il metodo Dipose() è privato, se lo si invia a IDisposable è possibile accedervi. Come altri hanno già detto, però, Clear() lo chiamerà per te.

Un approccio migliore, tuttavia, è quello di racchiudere la dichiarazione e e l'assegnazione della variabile in un utilizzando) blocco (:

byte[] hashCode; 

using(var hasher = new MD5CryptoServiceProvider()) 
{ 
    hashCode = hasher.ComputeHash(data); 
}