0

我正在制作一些测试用例,并注意到我需要检查 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 方法。

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

我应该检查每个项目而不是另一个吗?

4

3 回答 3

3

你试过这个Enumerable.SequenceEqual()方法吗?

这将遍历List's 中的每个项目并检查每个元素是否相等。它将使用您的对象的覆盖Equals()方法。

于 2012-09-27T22:46:17.960 回答
1

这是你要找的东西:Enumerable.SequenceEqual

返回 other.listItems.SequenceEqual(listItems);

于 2012-09-27T22:44:59.643 回答
1

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

反正。如果 listItems 是 a List<OtherObject>,则 List 类本身不会覆盖 Equals,因此它只使用比较哈希码的 Object 重载,而对于 Object,这些哈希码基于对象引用。因此,两个 List 变量只有在引用同一个 List 时才会相等。

要使其按您想要的方式工作,您需要遍历列表并比较项目。具体如何操作取决于顺序是否重要:

//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 复杂性,虽然您可能会改进它,但它会很复杂。

于 2012-09-27T23:02:44.773 回答