编程后端开发者 (VB.NET)

如何在 Visual Basic 中创建和使用字典(Dictionary),Dictionary 和 Hashtable 之间有什么区别,以及处理缺失键的特点是什么?

用 Hintsage AI 助手通过面试

答复。

问题背景:

在 VB.NET 中,使用键值对存储数据的标准是 Dictionary(Of TKey, TValue) 类。在经典的 VB6 中,通常使用 Scripting.Dictionary 对象或 Collection 集合,以及早期 .NET 版本中出现的 Hashtable 类型。这些结构可以快速根据键查找值,并取代了类型安全性较差的方法。

问题

Dictionary 和 Hashtable 之间的不明显区别,以及在搜索缺失键时可能发生的错误。例如,访问不存在的键在某些情况下会抛出错误,而在其他情况下则不会。另外,类型安全性和性能的差异会导致选择集合时出错。

解决方案

在现代版本的 VB.NET 中,最佳实践是使用 Dictionary(Of TKey, TValue),其中 TKey 和 TValue 是严格类型化的:

Dim dict As New Dictionary(Of String, Integer)() dict.Add("apple", 1) dict.Add("banana", 2) If dict.ContainsKey("banana") Then Console.WriteLine(dict("banana")) ' 将输出 2 End If ' 安全获取值 Dim value As Integer If dict.TryGetValue("cherry", value) Then Console.WriteLine(value) Else Console.WriteLine("没有这样的键!") End If

主要特点:

  • Dictionary(Of TKey, TValue) 工作更快,标准上是类型安全的,允许使用任意键(如果正确实现了 GetHashCode/Equals)。
  • Hashtable 接受和返回 Object,不支持泛型,速度较慢,在现代代码中不够方便。
  • 通过字典访问缺失键时会引发 KeyNotFoundException 异常。使用 ContainsKey 或 TryGetValue 进行安全访问。

含义的测试问题。

在字典中可以自由使用 Object 作为键吗?

形式上是可以的,但要求实现作为键的类的 GetHashCode 和 Equals 方法。否则可能会发生冲突和搜索错误。

如果通过 dict("foo") 访问不存在的键,将会发生什么?

将抛出 KeyNotFoundException 异常。如果没有预先检查键(通过 ContainsKey 或 TryGetValue),程序将崩溃。

Dictionary 和 Hashtable 是否支持相同的元素顺序?

否。这两个类都不保证元素的添加顺序。要保持顺序,可以使用 SortedDictionary、OrderedDictionary 或其他结构。

常见错误和反模式

  • 在未检查键是否存在的情况下访问字典中的值。
  • 在没有迫切需要的情况下在现代代码中使用 Hashtable — 缺乏类型安全性。
  • 使用哈希代码不稳定的对象作为键(例如,可变对象)。

实际案例

负面案例

开发者选择 Hashtable 来存储大量用户数据。出现了难以捕捉的错误 — 相同的键并不总是匹配,测试中出现了 Object.ReferenceEquals 错误,绑定了不稳定的键类型。

优点:

  • 快速原型开发,最小可行的解决方案。

缺点:

  • 难以调试。
  • "Object" 类型的集合 — 难以追踪类型错误。
  • 不支持 TryGetValue。

正面案例

转而使用 Dictionary(Of Guid, User):严格类型化,支持 TryGetValue,消除了冲突错误。性能得到了提升。

优点:

  • 可预测的行为。
  • 没有类型错误,调试时间更少。

缺点:

  • 如果使用自定义类型的键,则需要实现正确的 GetHashCode/Equals。