.NET:释放 HashAlgorithm 对象

7

从HashAlgorithm派生的对象(例如MD5CryptoServiceProvider)具有Dispose()方法,但它是私有的。相反,它有一个Clear()方法,该方法“释放”使用它的所有资源。

什么鬼?

这样才是正确处理HashAlgorithm的方式吗?

var hasher = new MD5CryptoServiceProvider();

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

hasher.Clear();

有人能解释一下这个吗? :)

如果可能的话,我建议您使用另一种哈希算法,因为许多人认为在某些应用程序中MD5哈希是不安全的。一个很好的替代方案是SHA系列,如SHA 256。它们也可以在.NET中使用。 - Skurmedel
1
好的,我记得几年前曾经证明MD5是有漏洞的。天哪,这是来自维基百科的:“2006年3月18日,Klima发表了一种算法[10],可以在单个笔记本电脑上的一分钟内找到碰撞,他使用了一种称为隧道的方法。” - core
以下是有关编程的内容,请将其从英语翻译成中文。仅返回已翻译的文本:FYI,“为什么首先要实现IDisposable?”在这里讨论:https://dev59.com/1rfna4cB1Zd3GeqPysaq - Brondahl
3个回答

13

Dipose()方法是私有的,但如果将其强制转换为IDisposable,您就可以访问它。正如其他人所说,Clear()会为您调用它。

然而,更好的方法是将变量的声明和赋值封装在using()块中:

byte[] hashCode;

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

5
使用Reflector查看,HashAlgorithmClear方法只是调用了私有的Dispose方法。暴露出一个名为Clear的方法的原因可能只是该类的设计者认为这是哈希算法更合适的名称。在BCL的其他部分中也可以看到类似的风格,比如System.IO.StreamClose方法。此外,最佳实践是使用using块,这将在完成时自动调用私有的Dispose方法。

1
正如其他人所提到的,最好使用 using 块,这样可以为您简化 try-finally/dispose 逻辑,并且是推荐的做法。 - Noldorin
另外,请注意反射还显示Dispose方法只是将内部数组清零。它甚至没有释放数组(没有设置为null),而是调用Array.Clear。它似乎没有释放任何句柄或其他非托管资源。我认为,如果有人“忘记”释放此类,则除了在内存中留下先前的哈希值的安全问题之外,不会出现任何泄漏或问题。 - iQueue

-5

你应该让垃圾回收器来处理这个问题,那是它的工作。

有些资源需要被释放,比如数据库连接和文件句柄,所以把它们放在 using 块中(C#)。但这不是这种情况。


4
即使类实现了IDisposable接口,也不意味着它需要手动释放。不过这取决于个人喜好。 - Alex Fort
4
@Alex:实际上这是完全不正确的。如果它实现了IDisposable,你总是应该显式地调用Dispose()。虽然良好的设计应该说,如果您的代码出现错误而未能调用Dispose(),类的终结器应该调用Dispose(),但在技术上没有任何要求。如果它实现了IDisposable,就调用Dispose()。 - Adam Robinson
HashAlgorithm 实现了 IDisposable 接口。 - Simon
1
@AdamRobinson 你在代码中是否处理了所有的 Tasks - Shadow
供参考,是否需要以及其作用在这里进行了讨论:https://dev59.com/1rfna4cB1Zd3GeqPysaq - Brondahl
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接