【问题标题】:Why SequenceEqual for List<T> returns false?为什么 List<T> 的 SequenceEqual 返回 false?
【发布时间】:2021-11-10 07:07:25
【问题描述】:

您好,当我遇到这样的情况时,sequenceEqual 有一些问题:

Sentence s1 = new Sentence { Text = "Hi", Order = 1 };
Sentence s2 = new Sentence { Text = "Hello", Order = 2 };
List<Sentence> list1 = new List<Sentence> { s1, s2 };
List<Sentence> list2 = new List<Sentence> { s1, s2 };

这很好用

bool equal = list1.SequenceEqual(list2);

并返回true

但是当我有一些返回List&lt;Sentence&gt;的方法时 例如:

public List<Sentence> Getall()
    {
        Sentence s1 = new Sentence { Text = "Hi", Order = 1 };
        Sentence s2 = new Sentence { Text = "Hello", Order = 2 };

        return new List<Sentence> { s1, s2 };
    }

并像这样使用它:

List<Sentence> list1 = Getall();
List<Sentence> list2 = Getall();

然后简单地检查一下

bool equal = list1.SequenceEqual(list2);

它返回'false',请告诉我为什么?以及如何让它发挥作用?

【问题讨论】:

  • 因为在第二种情况下它们是不同的对象,即它们的 GetHash() 方法返回不同的值。在第一种情况下,它们是具有两个不同引用的完全相同的对象。

标签: c# list comparison


【解决方案1】:

您的问题是一个new Sentence { Text = "Hi", Order = 1 } 不等于另一个new Sentence { Text = "Hi", Order = 1 }。尽管内容相同,但您有两个单独的对象,除非您设计了您的类,否则它们彼此不相等,除非它们实际上是相同的对象(如您的第一个示例中所示)。

您的Sentence 类至少需要覆盖EqualsGetHashCode,此时您的SequenceEquals 应该可以再次工作。

【讨论】:

  • 这个答案很接近,但建议使用 IEqualityComparer 的 Patryk Ćwiek 的答案是我的解决方案。
【解决方案2】:

作为MSDN states here

通过使用其类型的默认相等比较器比较元素来确定两个序列是否相等。

在你的例子中Sentence 是一个引用类型,默认EqualsGetHashCode,这意味着它将为每个元素使用引用相等。

您可以随时使用overload which accepts IEqualityComparer

【讨论】:

  • 关于使用比较器而不是在类本身中定义行为的可能性的好点。
【解决方案3】:

每次调用Getall() 时,您都会创建两个新的 Sentence 实例。在比较列表中的元素时,SequenceEqual 将使用默认的相等比较器,它基本上只是检查它们是否引用同一个对象:它们没有,所以它们是不同的。

您可以做的是覆盖序列中的Equal()== 运算符,以检查其他属性(如文本和顺序)是否相等。

或者你可以写一个IEqualityComparer&lt;Sequence&gt;并将它传递给SequenceEqual

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-09
    • 1970-01-01
    • 2010-12-26
    • 2022-12-21
    • 1970-01-01
    • 2013-09-18
    相关资源
    最近更新 更多