3

使用类结构列表时我遇到了无穷无尽的麻烦——我一直在尝试在控制台中制作字典。列表中的每个元素都有四个属性:.Word、.Definition、.Example 和 .IsDefined 布尔属性。该类如下所示:

Class Term
    Public Word As String
    Public Definition As String
    Public Example As String
    Public IsDefined As Boolean
End Class

我正在尝试编写的 sub 应该通过查找给定值的索引来更改列表中的值,然后它要求用户输入新数据,然后它应该更改对象。只有它在这里失败:

IndexPosition = TerminologyDictionary.IndexOf(Term1)

TerminologyDictionary 是一个 List(Of Term),而 Term1 是用户要求编辑的术语对象。TerminologyDictionary 中只有一个元素,它的所有四个属性都与 Term1 完全相同。我什至使用 QuickWatch 进行了检查,这些语句......

TerminologyDictionary(0).Word = Term1.Word
TerminologyDictionary(0).Definition = Term1.Definition
TerminologyDictionary(0).Example = Term1.Example
TerminologyDictionary(0).IsDefined = Term1.IsDefined

...无论我使用 Is 运算符还是等号,都评估为 True。但是当我测试 TerminologyDictionary(0) Is Term1 时,它返回 false。

我已经通过使用我自己的函数来遍历列表并手动测试每个属性并在它们都为真时返回一个索引来解决这个问题,但这很混乱,我想知道是否有一些简单的我做错了,或者如果有某种方法可以使用 .IndexOf。我知道有.FindIndex,但我不了解整个谓词,.IndexOf 要简单得多。

有人对出了什么问题有任何建议吗?提前致谢!

4

2 回答 2

3

默认情况下IndexOf仅通过引用进行比较,因为您的自定义类没有被覆盖Equals。当你覆盖Equals你应该总是覆盖GetHashCode

所以这应该工作:

Class Term
    Public Word As String
    Public Definition As String
    Public Example As String
    Public IsDefined As Boolean

    Public Overrides Function Equals(obj As Object) As Boolean
        Dim t2 = TryCast(obj, Term)
        If t2 Is Nothing Then Return False

        Return Word = t2.Word AndAlso
            Definition = t2.Definition AndAlso
            Example = t2.Example AndAlso
            IsDefined = t2.IsDefined
    End Function

    Public Overrides Function GetHashCode() As Integer
        Dim hash As Integer = 23
        hash *= 17 + Word.GetHashCode()
        hash *= 17 + Definition.GetHashCode()
        hash *= 17 + Example.GetHashCode()
        hash *= 17 + IsDefined.GetHashCode()

        Return hash
    End Function
End Class

编辑:也许这种实现GetHashCode更好,因为 VB.NET 缺乏unchecked

Public Overrides Function GetHashCode() As Integer
    Return New With {Word, Definition, Example, IsDefined}.GetHashCode()
End Function

它的效率较低,因为每次GetHashCode调用都需要创建一个匿名类型的实例。

于 2013-03-30T23:55:32.287 回答
1

IndexOf方法对列表中的类型使用标准比较,对于引用类型,标准比较比较对象的引用,而不是对象属性中的值。

您可以使用这样的FindIndex方法:

IndexPosition = TerminologyDictionary.FindIndex(Function(term As Term) _
  Term1.Word = term.Word and _
  Term1.Definition = term.Definition and _
  Term1.Example = term.Example and _
  Term1.IsDefined = term.IsDefined _
)
于 2013-03-30T23:56:16.137 回答