如何在全局List(Of)中克隆VB.NET本地对象
解决方案:给全局List添加对象的克隆副本
首先明确问题核心:你遇到的情况不是因为本地对象超出作用域被销毁,而是手动调用了Dispose()释放了对象资源,同时List中保存的是对象的引用,所以List里的对象也处于不可用状态。要让List独立持有对象的副本,需要实现对象的克隆机制。
在VB.NET中,实现对象克隆主要有两种常用方式:
方式1:实现ICloneable接口
让你的ClassObject类实现ICloneable接口,重写Clone方法,根据需求选择浅克隆或深度克隆:
1.1 修改ClassObject类
Public Class ClassObject Implements ICloneable Private _name As String Public Sub New(name As String) _name = name End Sub Public Function FuncGetstrName() As String Return _name End Function ' 实现ICloneable接口 Public Function Clone() As Object Implements ICloneable.Clone ' 浅克隆:复制值类型成员,引用类型成员仅复制引用 ' 如果需要深度克隆,需要手动复制所有引用类型成员 Return Me.MemberwiseClone() End Function ' 如果有Dispose方法,确保只释放当前对象的资源 Public Sub Dispose() ' 这里写释放资源的逻辑,比如关闭文件、释放非托管资源等 _name = Nothing ' 示例操作 End Sub End Class
1.2 修改添加对象到List的逻辑
在Button1_Click中,添加克隆后的对象到List:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click myClass1 = New ClassObject("aaa") MsgBox("object name: " & myClass1.FuncGetstrName()) ' 添加克隆副本到List,而不是原对象引用 listOfObjects.Add(DirectCast(myClass1.Clone(), ClassObject)) MsgBox("class name1: " & listOfObjects.Item(0).FuncGetstrName()) myClass1.Dispose() myClass1 = Nothing ' 现在List中的是独立副本,不受原对象Dispose的影响 MsgBox("class name2: " & listOfObjects.Item(0).FuncGetstrName()) End Sub
方式2:手动编写克隆方法
如果不想实现ICloneable接口,可以在ClassObject中自定义克隆方法,手动复制所有属性:
2.1 修改ClassObject类
Public Class ClassObject Private _name As String Public Sub New(name As String) _name = name End Sub Public Function FuncGetstrName() As String Return _name End Function ' 自定义克隆方法 Public Function Clone() As ClassObject ' 手动创建新实例并复制所有成员 Dim clonedObj As New ClassObject(Me._name) ' 如果有其他引用类型成员,需要在这里手动克隆 Return clonedObj End Function Public Sub Dispose() _name = Nothing End Sub End Class
2.2 修改添加逻辑
' 添加克隆副本 listOfObjects.Add(myClass1.Clone())
浅克隆 vs 深度克隆
- 浅克隆:仅复制对象的表层值类型成员,引用类型成员会共享原对象的引用(比如如果
ClassObject有一个List(Of String)成员,浅克隆后副本和原对象会共用同一个List)。 - 深度克隆:会递归复制所有引用类型成员,生成完全独立的对象副本。如果你的类包含引用类型成员,需要在克隆方法中手动处理这些成员的克隆。
内容的提问来源于stack exchange,提问作者ANDREW
相关产品推荐
相关产品推荐

