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

.net Equals似乎调用了错误的Equals方法,.net,vb.net,overloading,equals,.net,Vb.net,Overloading,Equals,我实现了一个PagedModel类来包装IEnumerable,以便在我的MVC应用程序中为网格提供分页数据。我使用Resharper自动生成的相等代码告诉它检查数据、总行数、页码和页面大小字段。以下是课程代码: Public Class PagedModel(Of T) Public Property PageSize As Integer Public Property PageNumber As Integer Public Property ModelData A

我实现了一个PagedModel类来包装IEnumerable,以便在我的MVC应用程序中为网格提供分页数据。我使用Resharper自动生成的相等代码告诉它检查数据、总行数、页码和页面大小字段。以下是课程代码:

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.\u ModelData,\u ModelData)的调用很奇怪,比如,这检查它是否是同一个对象,而不是包含的项是否相同。因为我的测试无论如何都失败了,所以我继续把它改成了另一个。_ModelData.Equals(_ModelData),但没有成功。然后我在调试时对它进行了反思,发现另一个。_ModelData.GetType().GetMethod(“Equals”,{GetType(Object)})!显然,这将导致比较失败

我提出了一个创建EnumerableEquals方法的解决方案,该方法比较两个enumerables中的每个项,以确认它们是相同的,但它看起来很草率。我能用normal.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
您不能真正使用“normal”Equals方法,因为它不是为可枚举项定义的(即,它不进行元素比较)。你所拥有的是非常好的(*),但是如果你想使用<代码>等于语法,你可以考虑使用“StriplingWarrior建议”。 (*)您的实现并没有真正检查两者是否相等。如果“a”的元素数大于“b”,则返回True;此外,如果“a”的元素与“b”相同,但顺序不同,它也将返回True。如果这对您的场景合适,那么就可以了。

您可能想要使用


这将确保两个IEnumerable具有相同顺序的相同元素。

通常,对于任意两个存储位置
X
Y
,除非写入
X
Y
,否则
X.Equals(Y)
的值不得更改。虽然不可变集合类型可以重写
Equals
来测试序列相等性,但可变类类型不能明智地使用
Equals(Object)
执行任何操作,只能测试引用标识(这是默认行为)。

谢谢,错过了这一步。更新了我的答案,指向你的答案。正是我需要的。为什么他们不把normalequals方法作为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