10

对正确组合组成哈希码的帮助者的搜索GetHashCode()似乎引起了一些敌意。我从评论中得到的印象是,一些 C# 开发人员认为您不应该GetHashCode()经常重写——当然,一些评论者似乎认为帮助获得正确行为的库是无用的。这样的功能在 Java 中被认为足够有用,以至于Java 社区要求将其添加到 JDK中,现在它在 JDK 7中。

是否有一些根本原因在 C# 中您不需要 - 或者绝对不应该 -像在 Java 中那样经常覆盖GetHashCode()(并且相应地, )?Equals()我发现自己经常使用 Java 执行此操作,例如,每当我创建一个我知道我想保留在 a 中HashSet或用作 a 中的键的类型时HashMap(相当于 .net Dictionary)。

4

3 回答 3

1

C# 具有提供值相等的内置值类型,而 Java 没有。因此,用 Java 编写自己的哈希码可能是必要的,而用 C# 编写可能是过早的优化。

编写一个类型以用作在 Dictionary/HashMap 中使用的复合键是很常见的。通常在此类类型上,您需要值相等(equivalence)而不是引用相等(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()and 。GetHashCode()

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

Java 没有这样的内置语言特性。如果要创建具有值相等语义的类型以用作复合键,则必须自己实现 equals() 和相应的 hashCode()。(有第三方帮助程序和库可以帮助您执行此操作,但语言本身没有内置任何内容)。

我将 C# 值类型描述为在 Dictionary 中使用时“可能效率低下”,因为:

于 2013-08-06T12:53:03.040 回答
0

我编写了一个辅助类来实现GetHashCode()Equals()CompareTo()使用属性数组中的值语义。

于 2013-08-05T21:44:24.013 回答
0

If your object represents a value or type, then you SHOULD override the GetHashCode() along with Equals. I never override hash codes for control classes, like "App". Though I see no reason why even overriding GetHashCode() in those circumstances would be a problem as they will never be put in a position to interfere with collection indexing or comparisons.

Example:

public class ePoint : eViewModel, IEquatable<ePoint>
{
    public double X;

    public double Y;

    // Methods

    #region IEquatable Overrides

    public override bool Equals(object obj)
    {
        if (Object.ReferenceEquals(obj, null)) { return false; }

        if (Object.ReferenceEquals(this, obj)) { return true; }

        if (!(obj is ePoint)) { return false; }

        return Equals((ePoint)obj);
    }

    public bool Equals(ePoint other)
    {
        return X == other.X && Y == other.Y;
    }

    public override int GetHashCode()
    {
        return (int)Math.Pow(X,Y);
    }

    #endregion
于 2013-08-05T20:13:25.890 回答