[英]SequenceEqual not calling Equals in parent type
A parent type: 父类型:
public class IdObject : IComparable<IdObject>, IEquatable<IdObject>
{
public int id { get; set; }
public bool Equals(IdObject other)
{
if (other == null) return this == null;
if (this == null) return false;
var test = other.id.CompareTo(this.id);
return other.id.CompareTo(this.id) == 0;
}
public int CompareTo(IdObject other)
{
return other.id.CompareTo(this.id);
}
}
A child: 一个孩子:
public class NamedObject : IdObject
{
public string name { get; set; }
}
Comparing lists of IdObject
s 比较
IdObject
的列表
var list1 = new List<IdObject>()
{
new IdObject() { id = 42 },
new IdObject() { id = 43 }
};
var list2 = new List<IdObject>()
{
new IdObject() { id = 43 },
new IdObject() { id = 42 }
};
list1.Sort();
list2.Sort();
var test = list1.SequenceEqual(list2); // True
Comparing lists of Named
s 比较
Named
的列表
var list1 = new List<NamedObject>()
{
new NamedObject() { id = 42 },
new NamedObject() { id = 43 }
};
var list2 = new List<NamedObject>()
{
new NamedObject() { id = 43 },
new NamedObject() { id = 42 }
};
list1.Sort();
list2.Sort();
var test = list1.SequenceEqual(list2); // False
I realized that IdObject::Equals
is not called through a NamedObject
context. 我意识到没有通过
NamedObject
上下文调用IdObject::Equals
。
Am I doing something wrong ? 难道我做错了什么 ?
Isn't supposed to call the inherited Equals
? 不应称呼继承的
Equals
吗?
How can I use the parent's Equals
? 如何使用父母的
Equals
?
Basically, you've got a problem because your type doesn't override object.Equals(object)
in a way consistent with your IEquatable<T>
implementation and you're dealing with a collection of the subclasses. 基本上,您会遇到问题,因为您的类型不会
object.Equals(object)
与IEquatable<T>
实现一致的方式覆盖object.Equals(object)
, 并且您正在处理子类的集合。
SequenceEqual
will be using EqualityComparer<NamedObject>.Default
. SequenceEqual
将使用EqualityComparer<NamedObject>.Default
。 That will check whether NamedObject
implements IEquatable<NamedObject>
- and will find that it doesn't, so it will fall back to calling object.Equals(object)
. 这将检查
NamedObject
是否实现IEquatable<NamedObject>
-并发现它没有实现,因此将退回到调用object.Equals(object)
。 You can see this here: 您可以在这里看到:
using System;
using System.Collections.Generic;
public class Base : IEquatable<Base>
{
public override bool Equals(object other)
{
Console.WriteLine("Equals(object)");
return false;
}
public bool Equals(Base other)
{
Console.WriteLine("Equals(Base)");
return false;
}
public override int GetHashCode() => 0;
}
public class Derived : Base
{
}
public class Test
{
static void Main()
{
var comparer = EqualityComparer<Derived>.Default;
Console.WriteLine(comparer.Equals(new Derived(), new Derived()));
}
}
You don't override object.Equals(object)
, so you've effectively got reference equality. 您不会覆盖
object.Equals(object)
,因此您实际上已经获得了引用相等性。
I would recommend that you override object.Equals(object)
and object.GetHashCode()
in your base class. 我建议您在基类中重写
object.GetHashCode()
object.Equals(object)
和object.GetHashCode()
。
You could then also implement IEquatable<NamedObject>
in NamedObject
, just delegating to the base implementation or (better) checking the name as well, unless you really don't want that to be taken into account. 然后,您还可以在
NamedObject
实现IEquatable<NamedObject>
,仅委托给基本实现或(更好地)检查名称,除非您确实不希望将其考虑在内。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.