C# 制作列表<;MyItem>;物体相等吗?

C# 制作列表<;MyItem>;物体相等吗?,c#,list,equality,C#,List,Equality,我正在做一些测试用例,注意到我需要检查MyObject是否与另一个MyObject相等 我创建了Equals方法,如下所示: public override bool Equals(object obj) { if (ReferenceEquals(null, obj)) return false; if (ReferenceEquals(this, obj)) return true; return obj.GetType() == typeof(MyObject) &

我正在做一些测试用例,注意到我需要检查MyObject是否与另一个MyObject相等

我创建了Equals方法,如下所示:

public override bool Equals(object obj)
{
    if (ReferenceEquals(null, obj)) return false;
    if (ReferenceEquals(this, obj)) return true;
    return obj.GetType() == typeof(MyObject) && Equals((MyObject) obj);
}

public bool Equals(MyObject other)
{
    if (ReferenceEquals(null, other)) return false;
    if (ReferenceEquals(this, other)) return true;
    return Equals(other.listItems, listItems);
}

public override int GetHashCode()
{
    return (TimeBlocks != null ? TimeBlocks.GetHashCode() : 0);
}
有一个名为listItems的列表的计算结果不是真的。listItem是另一种对象类型,它在Equals方法上具有重写

列表如何决定一个列表是否等于另一个列表


我是否应该将每个项目与其他项目进行对比?

这就是您要查找的内容:


返回其他.listItems.SequenceEqual(listItems)

这就是你想要的吗:

返回其他.listItems.SequenceEqual(listItems)

你试过这个方法吗

这将迭代两个
列表中的每个项目,并检查每个元素是否相等。它将使用对象的重写
Equals()
方法。

您尝试过该方法吗


这将迭代两个
列表中的每个项目,并检查每个元素是否相等。它将使用对象的重写
Equals()
方法。

首先,获取MyObject的Equals重载将
列表项
视为静态。如果是这样的话,那就这样吧,但我猜那是一个打字错误,
MyObject.listItems
应该是
other.listItems

无论如何。如果listItems是一个
列表
,则List类本身不会覆盖Equals,因此它只使用比较哈希代码的对象重载,对于对象,这些哈希代码基于对象引用。因此,只有当两个列表变量引用同一个列表时,它们才会相等

要使其按您想要的方式工作,您需要循环浏览列表并比较项目。具体做法取决于顺序是否重要:

//order-specific equality; true only if equal items are in the same order
public bool Equals(MyObject other)
{
    if (ReferenceEquals(null, other)) return false;
    if (ReferenceEquals(this, other)) return true;
    return other.listItems.Count == listItems.Count 
       && listItems.Select((l,i)=>other.listItems[i] == l).All(b=>b);
}

//order-independent equality; true if all items in one are in the other in any order
public bool Equals(MyObject other)
{
    if (ReferenceEquals(null, other)) return false;
    if (ReferenceEquals(this, other)) return true;
    return other.listItems.Count == listItems.Count 
       && listItems.Select((l,i)=>other.listItems.Contains(l)).All(b=>b);
}

第一种方法,给定两个相等的列表,将是线性的;第二个将是N^2复杂性,虽然您可能会对此进行改进,但它将是复杂的。

首先,接受MyObject的Equals的重载是将
列表项
视为静态的。如果是这样的话,那就这样吧,但我猜那是一个打字错误,
MyObject.listItems
应该是
other.listItems

无论如何。如果listItems是一个
列表
,则List类本身不会覆盖Equals,因此它只使用比较哈希代码的对象重载,对于对象,这些哈希代码基于对象引用。因此,只有当两个列表变量引用同一个列表时,它们才会相等

要使其按您想要的方式工作,您需要循环浏览列表并比较项目。具体做法取决于顺序是否重要:

//order-specific equality; true only if equal items are in the same order
public bool Equals(MyObject other)
{
    if (ReferenceEquals(null, other)) return false;
    if (ReferenceEquals(this, other)) return true;
    return other.listItems.Count == listItems.Count 
       && listItems.Select((l,i)=>other.listItems[i] == l).All(b=>b);
}

//order-independent equality; true if all items in one are in the other in any order
public bool Equals(MyObject other)
{
    if (ReferenceEquals(null, other)) return false;
    if (ReferenceEquals(this, other)) return true;
    return other.listItems.Count == listItems.Count 
       && listItems.Select((l,i)=>other.listItems.Contains(l)).All(b=>b);
}

第一种方法,给定两个相等的列表,将是线性的;第二个将是N^2复杂性,虽然您可能会在这方面有所改进,但它将是复杂的。

完美。谢谢你的回复!完美的谢谢你的回复+1好的,我相信一开始你的答案是正确的,尽管我当时并不理解。我实际上实现了Enumerable.SequenceEqual作为扩展方法,然后发现.net拥有它。我想我曾经对SequenceEqual有过一些问题,但我不记得是什么问题了。+1好的,我相信一开始你的答案是正确的,尽管当时我并不理解。我实际上实现了Enumerable.SequenceEqual作为扩展方法,然后发现.net有它。我想我曾经对SequenceEqual有过一些问题,但我不记得是什么问题了。你的排版很糟糕,谢谢。为什么不使用
Enumerable.SequenceEqual()
?没有理由;它与我的答案中的顺序相关版本几乎相同,如果有任何性能差异,您应该会看到最小的差异。然而,它将依赖于顺序;如果一个值为ABCDE的列表和一个值为ACDBE的列表应该相等,那么不能使用SequenceEquals。我确实希望看到尽可能多的实现。性能优化的第二条规则是“仅仅因为你看不到实现并不意味着它没有花费你”。Select和All都非常简单;我很清楚幕后发生了什么。SequenceEquals没有这么多。感谢您的澄清,我不一定需要这个例子,但肯定是一个更不稳定的选项。很可能最终会使用这个,谢谢!谢谢,你的打字打错了。为什么不使用
Enumerable.SequenceEqual()
?没有理由;它与我的答案中的顺序相关版本几乎相同,如果有任何性能差异,您应该会看到最小的差异。然而,它将依赖于顺序;如果一个值为ABCDE的列表和一个值为ACDBE的列表应该相等,那么不能使用SequenceEquals。我确实希望看到尽可能多的实现。性能优化的第二条规则是“仅仅因为你看不到实现并不意味着它没有花费你”。Select和All都非常简单;我很清楚幕后发生了什么。SequenceEquals没有这么多。感谢您的澄清,我不一定需要这个例子,但肯定是一个更不稳定的选项。很可能最终会使用这个,谢谢!