我用覆盖的Equals创建了类。问题是,Distinct方法对我的班级不起作用。
class MyClass
{
public int Item1 { get; private set; }
public int Item2 { get; private set; }
public MyClass(int item1, int item2)=>(Item1,Item2)=(item1,item2);
public override bool Equals(object obj)
{
var other = obj as MyClass;
if (other == null)
{
return false;
}
return (this.Item1 == other.Item1 && this.Item2 == other.Item2);
}
}
class Program
{
static void Main(string[] args)
{
MyClass x = new MyClass(1, 0);
MyClass y = new MyClass(1, 0);
var list = new List<MyClass>();
list.Add(x);
list.Add(y);
bool b = x.Equals(y)); //True
var distincts = list.Distinct(); //Doesn't work, contains both
}
}
我该如何解决这个问题?为什么它不能使用我的Equals in Distinct?
答案 0 :(得分:3)
Distinct
docs:
使用默认相等比较器来比较值,从序列中返回不同的元素。
让我们看看what the default equality comparer does:
Default
属性检查类型T是否实现System.IEquatable<T>
接口,如果是,则返回使用该实现的EqualityComparer<T>
。否则,它会返回使用T 提供的EqualityComparer<T>
和Object.Equals
覆盖的Object.GetHashCode
。
所以基本上,要做到这一点,你要么:
GetHashCode
IEquatable<T>
Distinct
的重载。如果我是你,我会选择第二个,因为你需要更改最少的代码。
class MyClass: IEquatable<MyClass> {
...
public bool Equals(MyClass obj)
{
if (obj == null)
{
return false;
}
return (this.Item1 == obj.Item1 && this.Item2 == obj.Item2);
}
}
答案 1 :(得分:2)
您还必须覆盖GetHashCode
:
public override int GetHashCode()
{
return Item1; // or something
}
Distinct
首先比较哈希码,这些哈希码应该比实际Equals
更快地计算。如果两个实例的哈希码相等,则Equals
只会被进一步评估。
答案 2 :(得分:1)
您需要在IEquatable<MyClass>
中实施MyClass
并提供您自己的GetHashCode
和Equals
方法的实施。
有关详细信息,请参阅this。
class MyClass
{
public int Item1 { get; private set; }
public int Item2 { get; private set; }
public MyClass(int item1, int item2)=>(Item1,Item2)=(item1,item2);
public override bool Equals(object obj)
{
var other = obj as MyClass;
if (other == null)
{
return false;
}
return (this.Item1 == other.Item1 && this.Item2 == other.Item2);
}
public override int GetHashCode()
{
return this.Item1;
}
}