我实现了一个PagedModel类来包装IEnumerable,以便为我的MVC应用程序中的网格提供分页数据。我使用了Resharper自动生成的Equality代码,告诉它检查数据,总行数,页码和页面大小字段。这是类代码:
Public Class PagedModel(Of T)
Public Property PageSize As Integer
Public Property PageNumber As Integer
Public Property ModelData As IEnumerable(Of T)
Public Property TotalRecords As Integer
Public Overloads Function Equals(ByVal other As PagedModel(Of T)) As Boolean
If ReferenceEquals(Nothing, other) Then Return False
If ReferenceEquals(Me, other) Then Return True
Return other._PageSize = _PageSize AndAlso other._PageNumber = _PageNumber AndAlso Equals(other._ModelData, _ModelData) AndAlso other._TotalRecords = _TotalRecords
End Function
Public Overloads Overrides Function Equals(ByVal obj As Object) As Boolean
If ReferenceEquals(Nothing, obj) Then Return False
If ReferenceEquals(Me, obj) Then Return True
If Not Equals(obj.GetType(), GetType(PagedModel(Of T))) Then Return False
Return Equals(DirectCast(obj, PagedModel(Of T)))
End Function
Public Overrides Function GetHashCode() As Integer
Dim hashCode As Long = _PageSize
hashCode = CInt((hashCode * 397) Xor _PageNumber Mod Integer.MaxValue)
If _ModelData IsNot Nothing Then hashCode = CInt(((hashCode * 397) Xor _ModelData.GetHashCode()) Mod Integer.MaxValue)
hashCode = CInt((hashCode * 397) Xor _TotalRecords Mod Integer.MaxValue)
Return CInt(hashCode Mod Integer.MaxValue)
End Function
End Class
我发现调用Equals(other._ModelData,_ModelData)特殊,作为AFAIK,它检查它是同一个对象而不是包含的项是相同的。因为我的测试无论如何都失败了,我继续将其更改为other._ModelData.Equals(_ModelData)但没有成功。然后我在调试时反思它,发现other._ModelData.GetType()。GetMethod(“Equals”,{GetType(Object)})。DeclaringType是Object!显然,这会导致失败的比较。
我想出了一个创建EnumerableEquals方法的解决方案,该方法比较两个枚举中的每个项目以确认它们是相同的,但它似乎很草率。有什么办法可以使用正常的.Equals方法吗?
Private Function EnumerableAreEqual(ByVal a As IEnumerable(Of T), ByVal b As IEnumerable(Of T)) As Boolean
b = b.ToList() 'avoid multiple query execution
Return a.All(Function(item) b.Contains(item))
End Function
答案 0 :(得分:5)
您可能想要使用SequenceEqual。
(new[]{1,2,3}).SequenceEqual(new[]{1,2,3}) // True
(new[]{1,2,3}).SequenceEqual(new[]{3,2,1}) // False
(new[]{1,2,3}).SequenceEqual(new[]{1,2}) // False
(new[]{1,2}).SequenceEqual(new[]{1,2,3}) // False
这将确保两个IEnumerables具有相同顺序的相同元素。
答案 1 :(得分:0)
你不能真正使用“普通”Equals方法,因为它没有为枚举定义(即,它不进行元素比较)。你有什么是完美的(*),但如果你想使用Equals
语法,你可以考虑使用@StriplingWarrior建议的内容。
(*)你的实现并没有真正检查两者是否相等。如果'a'的元素多于'b',它将返回True;另外,如果'a'与'b'具有相同的元素,但是以不同的顺序,它也将返回True。如果你的情况没问题,那就没关系了。
答案 2 :(得分:0)
通常,对于任意两个任意存储位置X
和Y
,X.Equals(Y)
的值永远不会更改,除非写入X
或Y
。虽然可变集合类型可以覆盖Equals
来测试序列相等性,但是可变类类型除了测试引用标识(这是默认行为)之外,不能明智地对Equals(Object)
做任何事情。 / p>