views:

117

answers:

3

Objects that derive from HashAlgorithm such as MD5CryptoServiceProvider have a Dispose() method, but it's private. Instead it has a Clear() method which "Releases all resources" used by it.

WTF?

Is this how to correctly dispose of a HashAlgorithm then?

var hasher = new MD5CryptoServiceProvider();

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

hasher.Clear();

Someone wanna explain this one to me? :)

A: 

You should let the GC handle that for you. That's it's job.

Some resources should be disposed of, like DB connections and file handles, so put those in a using block (C#). This isn't one of those cases, though.

Alex Fort
Actually, HashAlgorithm (and thus MD5CryptoServiceProvider) *do* implement IDisposable, therefore they should be properly disposed, either by calling the Clear method or with a `using` block.
Noldorin
Just because the class implements IDisposable, doesn't mean it needs to be disposed of manually. To each his own, though.
Alex Fort
No indeed, but the fact that it *does* implement IDisposable almost always strongly signifies that it ought to be manually disposed because it's doing some native interop inside. The GC will eventually get around to disposing it even if you don't explicitly call the method, but the time at which this occurs is not guaranteed to be soon
Noldorin
@Alex: Actually that's 100% incorrect. If it implements IDisposable, you are ALWAYS supposed to explicitly call Dispose(). While good design would say that the Finalizer on the class should call Dispose() if an error in your code failed to, there is nothing technically requiring that. If it implements IDisposable, call Dispose().
Adam Robinson
I guess you learn something new every day :)
Alex Fort
HashAlgorithm does implement IDisposable
Simon
A: 

Looking with Reflector, the Clear method of HashAlgorithm simply calls the private Dispose method. The reason for exposing a method with name Clear was probably just that the designers of the class thought it would be a more suitable name for a hash algorithm. You see similar styles within other parts of the BCL, such as Close for System.IO.Stream. Also, best practice here is to use a using block, which will automatically call the private Dispose method when it's finished.

Noldorin
As mentioned by others, it's best to use a `using` block anyway, which simplifies the try-finally/dispose logic for you, and is recommended practice.
Noldorin
+2  A: 

While the Dipose() method is private, if you cast it to IDisposable you can gain access to it. As others have said, though, Clear() will call it for you.

A better approach, however, is to enclose the declaration and and assignment of the variable in a using() block:

byte[] hashCode;

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