引用类型的默认相等比较器是引用相等,它仅true
在两个对象引用指向同一个实例(即通过单个new
语句创建)时返回。这与值类型不同,它测试值是否相等,并且true
如果它们的所有数据字段都相等(就像您的情况中的两个)一样,则会返回。更多信息:平等比较(C# 编程指南)。
如果你想改变这种行为,那么你需要IEquatable<T>
在你的类型上实现泛型接口,以便它比较实例的属性是否相等。操作员随后Distinct
会自动选择这个实现并产生预期的结果。
编辑IEquatable<Person>
:这是您班级的示例实现:
public class Person : IEquatable<Person>
{
public int Id { get; set; }
public int Name { get; set; }
public bool Equals(Person other)
{
if (other == null)
return false;
return Object.ReferenceEquals(this, other) ||
this.Id == other.Id &&
this.Name == other.Name;
}
public override bool Equals(object obj)
{
return this.Equals(obj as Person);
}
public override int GetHashCode()
{
int hash = this.Id.GetHashCode();
if (this.Name != null)
hash ^= this.Name.GetHashCode();
return hash;
}
}
从关于覆盖and运算符的指南(强调添加):==
!=
默认情况下,运算符==
通过确定两个引用是否指示同一个对象来测试引用是否相等。因此,引用类型不必==
为了获得此功能而实现运算符。当一个类型是不可变的,即包含在实例中的数据不能改变时,重载运算符==
来比较值相等而不是引用相等可能很有用,因为作为不可变对象,它们可以被认为是相同的,只要它们具有相同的价值。在非不可变类型中覆盖运算符不是一个好主意。==