如果没有为引用类型做任何特殊操作,则Equals()意味着引用相等(即相同的对象).如果我选择覆盖Equals()引用类型,它是否总是意味着两个对象的值是等价的?
考虑这个可变性 Person类:
class Person
{
readonly int Id;
string FirstName { get; set; }
string LastName { get; set; }
string Address { get; set; }
// ...
}
Run Code Online (Sandbox Code Playgroud)
表示完全相同的人的两个对象将始终具有相同的Id,但是其他字段可能随时间不同(即,在地址改变之前/之后).
对于这个对象,Equals可以定义为不同的东西:
Ids相等(代表同一个人但具有不同地址的两个对象将返回true)问题:这个课程中哪些(如果有的话)更适合?(或许问题应该是,"这个班级的大多数客户如何期望Equals()表现?")
笔记:
Hashsetor中使用这个类更加困难Dictionary使用Identity Equality使得Equals和=运算符之间的关系变得奇怪(即在检查两个Person对象(p1和p2)之后返回true)Equals(),您可能仍然希望更新引用以指向"较新的"Person对象,因为它是不等值).例如,以下代码读取奇怪 - 似乎它什么都不做,但它实际上是删除p1并添加p2:
HashSet<Person> people = new HashSet<Person>();
people.Add(p1);
// ... p2 is an new object that has the same Id as p1 but different Address
people.Remove(p2);
people.Add(p2);
Run Code Online (Sandbox Code Playgroud)相关问题:
Mar*_*ell 13
是的,为此决定正确的规则是棘手的.这里没有单一的"正确"答案,它将在很大程度上取决于上下文和偏好.就个人而言,我很少考虑它,只是在大多数常规POCO类中默认引用相等:
Person在哈希集中使用类似字典键/的东西的情况是最小的
int Id字典(等)作为键x==y给出相同结果是否x/ y是Person或object,或实际上T在通用方法Equals并且GetHashCode兼容,大多数事情都会解决,一个简单的方法就是不要覆盖它们但请注意,我总是建议相反的值类型,即显式覆盖Equals/ GetHashCode; 但是,写一个struct是非常罕见的
您可以提供多个IEqualityComparer(T)实现并让消费者决定.
例:
// Leave the class Equals as reference equality
class Person
{
readonly int Id;
string FirstName { get; set; }
string LastName { get; set; }
string Address { get; set; }
// ...
}
class PersonIdentityEqualityComparer : IEqualityComparer<Person>
{
public bool Equals(Person p1, Person p2)
{
if(p1 == null || p2 == null) return false;
return p1.Id == p2.Id;
}
public int GetHashCode(Person p)
{
return p.Id.GetHashCode();
}
}
class PersonValueEqualityComparer : IEqualityComparer<Person>
{
public bool Equals(Person p1, Person p2)
{
if(p1 == null || p2 == null) return false;
return p1.Id == p2.Id &&
p1.FirstName == p2.FirstName; // etc
}
public int GetHashCode(Person p)
{
int hash = 17;
hash = hash * 23 + p.Id.GetHashCode();
hash = hash * 23 + p.FirstName.GetHashCode();
// etc
return hash;
}
}
Run Code Online (Sandbox Code Playgroud)
另请参阅:重写的System.Object.GetHashCode的最佳算法是什么?
用法:
var personIdentityComparer = new PersonIdentityEqualityComparer();
var personValueComparer = new PersonValueEqualityComparer();
var joseph = new Person { Id = 1, FirstName = "Joseph" }
var persons = new List<Person>
{
new Person { Id = 1, FirstName = "Joe" },
new Person { Id = 2, FirstName = "Mary" },
joseph
};
var personsIdentity = new HashSet<Person>(persons, personIdentityComparer);
var personsValue = new HashSet<Person>(persons, personValueComparer);
var containsJoseph = personsIdentity.Contains(joseph);
Console.WriteLine(containsJoseph); // false;
containsJoseph = personsValue.Contains(joseph);
Console.WriteLine(containsJoseph); // true;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1348 次 |
| 最近记录: |