4

我需要为我的一种类型覆盖 Equals() 方法,但似乎我还必须覆盖 GetHashCode() 方法。

我不确定:

如果我有 Animal 类型并且我有 2 个 Animal 实例,它们基本上是相同的(相等)Cats;像:

Animal cat_01 = new Animal("Kitty", "Pink");
Animal cat_02 = new Animal("Kitty", "Pink");

我是否应该实现 GetHashedCode() 来为 cas_01 和 cat_02 保留相同的值,即使它们代表内存中的不同引用?

它是 GetHashCode() 应该工作的方式吗?

谢谢

4

3 回答 3

4

MSDN 说

如果两个对象比较相等,则每个对象的 GetHashCode 方法必须返回相同的值。

所以是的,GetHashCode 应该为两个实例返回相同的值。

如果您想查看它们是否引用同一个对象,您仍然可以使用 Object.ReferenceEquals。

于 2011-09-05T12:11:33.397 回答
3

我不同意其他答案。这个例子中的 Animal 不是一个值对象,两只猫可以具有相同的名称和颜色并且是完全不同的实体是完全可行的。从逻辑上讲,您是在说“这只猫和那只猫具有相同的名字和相同的颜色,因此它们是同一只猫”-这不一定是正确的..

我建议您将 Animal.Equals 保留为默认实现,并创建一个单独的 IEqualityComparer 实现,如果动物具有相同的名称/颜色,则返回 true。

public class AnimalNameColorComparer : IEqualityComparer<Animal>
{
    public bool Equals(Animal a, Animal b)
    {
        return a.Name == b.Name &&
               a.Color == b.Color
    }

    public int GetHashCode(Animal a)
    {
        return a.Name.GetHashCode() ^ a.Color.GetHashCode();
    }
}

试着记住,比较一只猫有很多不同的方法,一个单一的“等于”方法是不够的:)

// Create two black cats called fluffy...
var cat1 = new Cat("Fluffy", "Black");
var cat2 = new Cat("Fluffy", "Black");

cat1.Equals(cat2) == false; // they are not the same cat!

var comparer = new AnimalNameColorComparer();

comparer.Equals(cat1, cat2) == true; // But they do have the same name & colour...
于 2011-09-05T12:22:11.913 回答
1

根据模型的设计,如果它是值对象(不可变),那么 gethashcode 应该返回所有字段的哈希值,但另一方面,如果它是域实体,那么它应该有一个身份,这个身份应该用于比较和 gethashcode (两个人的名字和年龄不一样,如果你有两只同名的猫并不意味着它们是同一只猫!)。

检查: http: //moh-abed.com/2011/07/13/entities-and-value-objects/

于 2011-09-05T13:23:29.287 回答