当前位置 : 主页 > 编程语言 > c语言 >

.net – IEnumerable.Equals似乎调用了错误的Equals方法

来源:互联网 收集:自由互联 发布时间:2021-06-24
我实现了一个PagedModel类来包装IEnumerable,为我的MVC应用程序中的网格提供分页数据.我使用了Resharper自动生成的Equality代码,告诉它检查数据,总行数,页码和页面大小字段.这是类代码: Pub
我实现了一个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
你可能想用 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具有相同顺序的相同元素.

网友评论