我为什么不*覆盖GetHashCode()?

时间:2013-08-05 20:01:15

标签: 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#中你不需要 - 或者绝对不应该 - 像在Java中一样频繁地覆盖GetHashCode()(相应地,Equals())?我发现自己经常使用Java来做这件事,例如每当我创建一个我知道要保留在HashSet中的类型或者用作HashMap中的键时(等效地,.net {{1 }})。

3 个答案:

答案 0 :(得分:1)

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中的现有条目不匹配,因为它们具有不同的标识。 / p>

要获得价值平等,您需要以两种语言覆盖Equals()GetHashCode()

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

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

我将C#值类型描述为在字典中使用的“潜在低效”,因为:

答案 1 :(得分:0)

如果您的对象表示值或类型,那么您应该覆盖GetHashCode()和Equals。我从不覆盖控件类的哈希码,比如“App”。虽然我认为在这些情况下甚至覆盖GetHashCode()是没有理由的,因为它们永远不会干扰收集索引或比较。

示例:

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

答案 2 :(得分:0)

我使用属性数组中的值语义编写了helper class来实现GetHashCode()Equals()CompareTo()