You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

VB.NET列表中属性相同对象哈希值不同导致去重失败如何修复

问题成因

.NET 中引用类型默认的相等比较规则为引用相等,即判断两个变量是否指向堆内存中的同一个实例,而非判断实例的业务属性值是否相等。
你每次点击按钮都会通过New DocInfo(...)创建全新的对象实例,哪怕两个实例的title和fullPath属性完全一致,也属于不同的内存对象:

  • 默认的IList(Of T).Contains方法会基于引用相等判断,因此会认为新对象不存在于现有列表中
  • 默认的GetHashCode方法基于对象内存地址生成,所以你会看到属性相同的实例哈希值完全不同
解决方案

有两种常用实现方案,按需选择即可:

方案1:重写DocInfo类的相等比较逻辑

直接在DocInfo类中重写Equals和GetHashCode方法,将相等判断规则改为基于业务属性匹配,修改后原有AddUnique方法无需改动即可正常工作:

Class DocInfo
    Public Property title As String
    Public Property fullPath As String

    Sub New(title As String, fullPath As String)
        Me.title = title
        Me.fullPath = fullPath
    End Sub

    ' 重写相等判断逻辑,按title和fullPath判断两个实例是否等价
    Public Overrides Function Equals(obj As Object) As Boolean
        If obj Is Nothing OrElse Me.GetType() <> obj.GetType() Then
            Return False
        End If
        Dim other As DocInfo = CType(obj, DocInfo)
        Return Me.title = other.title AndAlso Me.fullPath = other.fullPath
    End Function

    ' 重写哈希值生成规则,用参与相等判断的属性计算哈希
    Public Overrides Function GetHashCode() As Integer
        ' .NET Core 2.1+ / .NET 5+ 支持HashCode.Combine
        Return HashCode.Combine(title, fullPath)
        ' 低版本.NET可替换为以下写法
        ' Dim hashTitle = If(title?.GetHashCode(), 0)
        ' Dim hashPath = If(fullPath?.GetHashCode(), 0)
        ' Return hashTitle Xor (hashPath << 1)
    End Function
End Class

方案2:修改扩展方法支持自定义比较规则

如果不方便修改DocInfo类,可以改造AddUnique扩展方法,支持传入业务比较规则,无需改动原有实体类:

优化后的扩展方法(性能优于原版,避免每次全列表遍历比较)

<Extension()>
Public Sub AddUniqueBy(Of T, TKey)(ByVal self As IList(Of T), ByVal items As IEnumerable(Of T), ByVal keySelector As Func(Of T, TKey))
    ' 用HashSet存储已有键,查询时间复杂度为O(1),元素量大时性能远高于原版的O(n)查询
    Dim existingKeys As New HashSet(Of TKey)(self.Select(keySelector))
    For Each item In items
        Dim key = keySelector(item)
        If Not existingKeys.Contains(key) Then
            self.Add(item)
            existingKeys.Add(key)
        End If
    Next
End Sub

调用示例

docsInfo.AddUniqueBy(candidateItems, Function(d) New With {d.title, d.fullPath})

内容的提问来源于stack exchange,提问作者Justin8051

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 14:18:04