我的 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# 中是否有一些根本原因不需要 - 或者绝对不应该 - 覆盖 GetHashCode()
(以及相应的 Equals()
)作为经常像在 Java 中一样?我发现自己经常用 Java 这样做,例如,每当我创建一个我知道我想保留在 HashSet
中或用作 HashMap
中的键时(等同于, .net 字典
).
最佳答案
C# 具有提供值相等性的内置值类型,而 Java 没有。因此,在 Java 中编写您自己的哈希码可能是必要的,而在 C# 中这样做可能是过早的优化。
编写一个类型以用作在字典/ 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
实现值相等,否则它不会匹配字典中的现有条目,因为它们具有不同的身份。
要获得值(value)平等,您需要重写 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!
关于c# - 为什么我不应该*覆盖 GetHashCode()?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18066690/