C# – 为什么我不会*覆盖GetHashCode()?

我的 search for a helper to correctly combine constituent hashcodes for GetHashCode()似乎有些敌意.我从评论中得到的印象是,一些C#开发人员不认为你应该经常覆盖GetHashCode() – 当然有些评论者似乎认为一个帮助获得行为的图书馆是无用的.这样的功能被认为对于 Java community to ask for it to be added to the JDK在Java中是有用的,而且是 now in JDK 7.

有没有一些根本原因,在C#中,您不需要 – 或绝对不应该像Java一样经常覆盖GetHashCode()(相应地,Equals())我发现自己经常使用Java,例如,每当我创建一个类型,我知道我想保留在一个HashSet或用作一个键在HashMap(等效的.net字典).

解决方法

C#具有提供值相等性的内置值类型,而Java不具有值.所以在Java中编写自己的哈希码可能是必须的,而在C#中编写它可能是一个过早的优化.

编写一个类型以用作在Dictionary / HashMap中使用的复合键是很常见的.通常这种类型,你需要value equality (equivalence) as opposed to reference equality(identity),例如:

IDictionary<Person,IList<Movie> > moviesByActor; // e.g. initialised from DB
// elsewhere...
Person p = new Person("Chuck","Norris");
IList<Movie> chuckNorrisMovies = moviesByActor[p];

在这里,如果我需要创建一个新的Person实例来执行查找,我需要Person来实现值等式,否则它将不匹配Dictionary中的现有条目,因为它们具有不同的身份.

为了获得值相等性,您需要以两种语言覆盖Equals()和GetHashCode().

C#的结构(值类型)implement value equality为您提供(尽管潜在效率低下),并提供了一致的GetHashCode实现.这可能足以满足许多人的需求,除非性能问题另有规定,否则他们不会进一步实施自己的改进版本.

Java没有这样的内置语言功能.如果要创建一个具有值相等语义的类型作为复合键,则必须自己实现equals()和相应的hashCode(). (有第三方帮助和图书馆可以帮助您做到这一点,但没有内置于语言本身).

我将C#值类型描述为“可能无效率”,用于“词典”,因为:

> The implementation of ValueType.Equals itself can sometimes be slow.这是用于字典查找.
> ValueType.GetHashCode的实现虽然正确,但可以产生许多冲突,导致非常差的字典性能.看看this answer to a Q by Jon Skeet,这表明KeyValuePair< ushort,uint>似乎总是产生相同的hashCode!

相关文章

在项目中使用SharpZipLib压缩文件夹的时候,遇到如果目录较深,则压缩包中的文件夹同样比较深的问题。比...
项目需要,几十万张照片需要计算出每个照片的特征值(调用C++编写的DLL)。 业务流程:选择照片...
var array = new byte[4]; var i = Encoding.UTF8.GetBytes(100.ToString(&quot;x2&quot;));//...
其实很简单,因为Combox的Item是一个K/V的object,那么就可以把它的items转换成IEnumerable&lt;Dic...
把.net4.6安装包打包进安装程序。 关键脚本如下: 头部引用字符串对比库 !include &quot;WordFunc....
项目需求(Winform)可以批量打印某个模板,经过百度和摸索,使用iTextSharp+ZXing.NetʿreeSp...