这个问题仅用于教育目的,我可以通过使用
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' 的情况下实现两个列表的比较?
您应该使用 [
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;
}