VB.NET中向数组添加类对象时覆盖所有数组项问题
类对象存入数组时被覆盖的原因
核心原因:引用类型与值类型的内存存储差异
问题本质是引用类型和值类型的行为差异导致的:
Itemproperties是自定义类,属于引用类型:这类对象的变量(比如Item)保存的是对象在堆内存中的地址,而非对象本身的数据。- 整数
Integer是值类型:变量直接保存数据本身,赋值时会创建数据的独立副本。
代码问题拆解
在第一个示例中:
Public Item As New Itemproperties ' 仅创建了一个对象实例 Private Sub ClassObjectToArray(sender As Object, e As EventArgs) For i As Integer = 0 To ItemStorage.Length - 1 Item.Hight = i + 1 ' 修改的是同一个对象的属性 ItemStorage(i) = Item ' 数组元素保存的是同一个对象的内存地址 Console.WriteLine(ItemStorage(0).Hight) Next End Sub
循环中你始终操作同一个Itemproperties实例:每次修改Item.Hight都是在更新这个唯一对象的属性,数组里的所有元素都指向该对象的内存地址。因此每次打印ItemStorage(0).Hight时,看到的都是当前对象的最新属性值,最终输出1 2 3 4 5 6 7。
而值类型示例中,x = i + 1是把数值复制给x,testarray(i) = x又将x的数值副本存入数组,每个数组元素都是独立的数值,所以testarray(0)始终是第一次存入的1,输出符合预期。
解决方法的原理
当你执行ItemStorage(i) = New Itemproperties时,每次循环都创建了一个新的Itemproperties实例,数组元素指向不同的内存地址,每个对象相互独立,修改新对象的属性不会影响之前存入数组的对象。
如果不想拆分属性赋值,更简洁的正确写法是在循环内直接创建新实例并赋值:
Private Sub ClassObjectToArray(sender As Object, e As EventArgs) For i As Integer = 0 To ItemStorage.Length - 1 Dim newItem As New Itemproperties() newItem.Hight = i + 1 ItemStorage(i) = newItem Console.WriteLine(ItemStorage(0).Hight) Next End Sub
此时数组里的每个元素都指向独立对象,ItemStorage(0)的属性值不会被后续循环修改,输出会符合预期的1 1 1 1 1 1 1。
内容的提问来源于stack exchange,提问作者Newt
相关产品推荐
相关产品推荐

