c# - 为什么我不应该*覆盖 GetHashCode()?

标签 c# java .net hash

我的 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# 值类型描述为在字典中使用时“可能效率低下”,因为:

关于c# - 为什么我不应该*覆盖 GetHashCode()?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18066690/

相关文章:

c# - 解析固定列宽的可变长度字符串 C#

java - 循环处理异常

asp.net - 在什么情况下 HttpContext.Current.Session 可以为 null?

.net - 通过身份验证自动从网站下载图片,第二部分

c# - Visual Studio 可以为事件自动创建内联本地匿名方法而不是创建具体方法吗?

c# - 连接字符串属性尚未初始化 SqlCommandBuilder

c# - 发布请求正文太大(参数对象中的字符串太大)

c# - 从字符串中获取多个数字

java - 如何使用有界类型参数扩展泛型类

java 历史 map - JavacTool java.lang.ClassNotFoundException