我的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 }})。
答案 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#值类型描述为在字典中使用的“潜在低效”,因为:
ValueType.Equals
itself can sometimes be slow。这用于字典查找。ValueType.GetHashCode
的实现,虽然正确,但可能会导致许多冲突,导致字典性能非常差。请查看this answer to a Q by Jon Skeet,其中显示总是会产生KeyValuePair<ushort, uint>
始终产生相同的hashCode !答案 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()
。