var people = new List<Person>
{
new Person
{
Id = 1,
Name = "Atish"
},
new Person
{
Id = 2,
Name = "Dipongkor"
},
new Person
{
Id = 1,
Name = "Atish"
}
};
Console.WriteLine(people.Distinct().Count());
Run Code Online (Sandbox Code Playgroud)
为什么输出3?
为什么不是2?
引用类型的默认相等比较器是引用相等,它仅true在两个对象引用指向同一实例时返回(即通过单个new语句创建).这与测试值相等的值类型不同,true如果所有数据字段相等(如您的情况中的两个),则返回值.更多信息:Equality Comparisons(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;
}
}
Run Code Online (Sandbox Code Playgroud)
从覆盖和运营商的指导方针(重点补充):==!=
默认情况下,运算符
==通过确定两个引用是否指示同一对象来测试引用相等性.因此,引用类型不必实现运算符==以获得此功能.当一个类型是不可变的,也就是说,实例中包含的数据不能被改变,重载运算符==来比较值的相等而不是引用相等可能是有用的,因为作为不可变对象,只要它们可以被认为是相同的具有相同的价值.在非不可变类型中覆盖运算符不是一个好主意==.