仅使用 LINQ 时使用 IEquatable 比较两个集合

问题描述 投票:0回答:1

这个问题仅用于教育目的,我可以通过使用

for
循环轻松解决它,该循环在第一次不匹配时返回
false

我正在

IEquatable<CustomerFeedbackViewModel>
上实现
CustomerFeedbackViewModel
,它有一个
QuestionViewModel
的集合,我需要逐个元素进行比较。

public class CustomerFeedbackViewModel 
{
    public List<QuestionViewModel> Questions { get; set; }

    public string PageName { get; set; }

    public string SessionId { get; set; }
}

当实现

Equals
而不是使用我上面提到的
for
循环时,我想使用
TrueForAll
方法,它看起来像下面这样。

public bool Equals(CustomerFeedbackViewModel other)
    {
        if (ReferenceEquals(null, other)) return false;
        if (ReferenceEquals(this, other)) return true;
        return Questions.TrueForAll((o,i) => o.Equals(other.Questions.ElementAt(i))) && string.Equals(PageName, other.PageName) && string.Equals(SessionId, other.SessionId);
    }

Ofc

TrueForAll
没有索引,以上永远不会飞。

如何在不使用

for
循环而是使用 linq 'oneliner' 的情况下实现两个列表的比较?

c# linq .net-4.5 ienumerable iequatable
1个回答
9
投票

您应该使用 [

Enumerable.SequenceEqual
][1]:

,而不是在所有索引上比较每个问题
return string.Equals(PageName, other.PageName) 
    && string.Equals(SessionId, other.SessionId) 
    && Questions.SequenceEqual(other.Questions);

如果您不在

Equals
中覆盖
GethashCode
+
QuestionViewModel
,您可以提供自定义
IEqualityComparer<QuestionViewModel>
并将其传递给
SequenceEqual
重载或实现
IEquatable<QuestionViewModel>
。 [1]:https://msdn.microsoft.com/library/bb348567(v=vs.100).aspx

编辑:一般来说,您应该初始化列表属性,例如通过构造函数或自动实现的属性。否则,你可以在任何地方得到空引用异常,例如在

Equals
中。

所以更好的

Equals
实施将是:

public bool Equals(CustomerFeedbackViewModel other)
{
    if (ReferenceEquals(null, other)) return false;
    if (ReferenceEquals(this, other)) return true;
     return string.Equals(PageName, other.PageName) 
        && string.Equals(SessionId, other.SessionId) 
        && Questions?.SequenceEqual(other.Questions) == true;
}
© www.soinside.com 2019 - 2024. All rights reserved.