C# 结果不同

C# 结果不同,c#,iequatable,C#,Iequatable,在下面的代码中,调用泛型列表上的SequenceEqual,当使用类泛型类型定义列表时(调用了equalTableClass.Equals)返回true(如预期) 若列表是用IEquatable接口定义的,则不调用Equals方法,结果为false(而是调用object.Equals,而不是在代码中) 问题是,为什么在第二种情况下不调用Equals.Equals方法 public class EquatableClass : IEquatable<EquatableClass> {

在下面的代码中,调用泛型列表上的
SequenceEqual
,当使用类泛型类型定义列表时(调用了
equalTableClass.Equals
)返回true(如预期)

若列表是用
IEquatable
接口定义的,则不调用Equals方法,结果为false(而是调用object.Equals,而不是在代码中)

问题是,为什么在第二种情况下不调用
Equals.Equals
方法

public class EquatableClass : IEquatable<EquatableClass>
{
        public string Name { get; set; }
        public bool Equals(EquatableClass other) => this.Name.Equals(other.Name);        
}

static void Main(string[] args)
{
    var A = new List<EquatableClass> {  new EquatableClass { Name = "A" } };
    var B = new List<EquatableClass> {  new EquatableClass { Name = "A" } };

    var result1 = A.SequenceEqual(B); // == true;

    var AA = new List<IEquatable<EquatableClass>> {  new EquatableClass { Name = "A" } };
    var BB = new List<IEquatable<EquatableClass>> {  new EquatableClass { Name = "A" } };

    var result2 = AA.SequenceEqual(BB); // == false;    
}
public类equalableclass:IEquatable
{
公共字符串名称{get;set;}
public bool Equals(equalTableClass other)=>this.Name.Equals(other.Name);
}
静态void Main(字符串[]参数)
{
var A=新列表{new equalableclass{Name=“A”};
var B=新列表{new equalableclass{Name=“A”};
var result1=A.SequenceEqual(B);//==true;
var AA=新列表{new equalableclass{Name=“A”};
var BB=新列表{new equalableclass{Name=“A”};
var result2=AA.SequenceEqual(BB);//==false;
}
SequenceEqual
方法将尝试查看它是否可以将
T
转换为
IEquatable
,如果可以,它将使用
IEquatable.Equals
表示相等

当您有一个
列表
时,它将尝试将
equalTableClass
转换为
IEquatable
,并且成功,因此它使用适当的
Equals
方法


当您有一个
列表时,它将尝试将
IEquatable
转换为
IEquatable
,这将失败,因为实际对象没有实现
IEquatable
,所以它会采用默认行为使用
object.Equals(object)
,您不会覆盖它。

因为参数与类参数不匹配。因此使用默认方法。这就是为什么如果要实现
IEquatable
,也应该重写
Equals(object)
的行为以匹配该行为。始终还要重写
Equals
(+
GetHashCode
),例如:
公共重写bool Equals(object obj){EquatableClass other=obj as EquatableClass;return obj!=null&&other.Equals(this);}
Ok,据我所知,它可以简化为:
typeof(IEquatable)。IsAssignableFrom(typeof(EquatableClass))==false
原因是IEquatable接口泛型参数声明为不变量,对吗?@user4662448如果
IEquatable
是协变的或逆变的,则不会有任何不同。该转换不适用于该类型的任何情况。它需要实际实现
Iequalable
并添加额外的
Equals
方法以使其工作。(这显然不是一个好主意)但是添加额外的
Equals
不起作用,object。Equals会被调用…@user4662448如果您添加第二个
IEquatable
实现,它将被使用。您不想这样做。错误在于您在不应该的时候将列表键入为
IEquatable
。正确的解决方案是使用您所输入类型的列表实际上,你有比较的能力,这是一个
equatable类
而不是
IEquatable>
,但是如果你添加了额外的
IEquatable
实现,你至少会看到发生了什么,尽管你不应该把它保存在你的代码中将实现添加到
Equals(IEquatable other)
方法的
Equals(IEquatable other)
中。为什么?(我个人的观点是,它与IEquatable的不变性有关……但我可能错了)。