1. 问题现象:当结构体和类作为字典键时的差异
在VB.NET开发中,Dictionary(Of K, V)是最常用的集合类型之一。最近我在开发一个机房管理系统时,遇到了一个有趣的现象:当使用结构体(Structure)作为字典键时,两个属性相同的实例会被视为同一个键;而使用类(Class)作为键时,即使属性完全相同,也会被视为不同的键。
来看一个实际案例。假设我们要用字典存储不同位置的电脑信息,位置由行号和列号组成:
vb复制' 类作为键
Public Class Location_Class
Public Row As Integer
Public Col As Integer
End Class
' 结构体作为键
Public Structure Location_Struct
Public Row As Integer
Public Col As Integer
End Structure
当我们将这两个类型分别作为字典键使用时,会出现完全不同的行为:
vb复制Dim dictClass As New Dictionary(Of Location_Class, ComputerInfo)
Dim dictStruct As New Dictionary(Of Location_Struct, ComputerInfo)
Dim classKey1 As New Location_Class With {.Row = 1, .Col = 2}
Dim classKey2 As New Location_Class With {.Row = 1, .Col = 2}
' dictClass会包含两个条目
Dim structKey1 As New Location_Struct With {.Row = 1, .Col = 2}
Dim structKey2 As New Location_Struct With {.Row = 1, .Col = 2}
' dictStruct只会保留最后一个条目
注意:这个差异在开发中很容易被忽视,特别是当开发者在结构体和类之间切换时,可能会导致难以发现的逻辑错误。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 底层原理:值类型与引用类型的本质区别
2.1 内存分配方式的差异
结构体是值类型(Value Type),存储在栈(stack)上(注:实际上可能存储在堆上,取决于上下文)。当创建结构体实例时,直接存储的是值本身。而类是引用类型(Reference Type),存储在堆(heap)上,变量存储的是指向堆内存的引用。
这种差异导致了它们在字典中的不同行为:
- 结构体作为键时,字典比较的是实际的值
- 类作为键时,字典比较的是引用地址
2.2 默认的相等性比较实现
Dictionary判断键是否相
