Vb.net Net将哈希表和字符串传递给递归过程
这里我有一个递归程序。似乎每当Vb.net Net将哈希表和字符串传递给递归过程,vb.net,string,recursion,hashtable,Vb.net,String,Recursion,Hashtable,这里我有一个递归程序。似乎每当哈希表被传递到递归过程(ByVal或ByRef)时,即使退出该过程,它也会留在内存中。该字符串在每次调用过程时都会保留在内存中,但在退出过程时会消失,因为它是通过ByVal传递的。这两个物体是被区别对待的,还是我的理解有偏差 在form1_load的末尾,为什么ht.count总是等于4,而不管它是通过byref还是byval传递的 我认为ht.count和str的长度应该始终相同,因为两者都是通过val传递的。为什么不是这样 谢谢你的帮助和理解!如果我需要说得更清
哈希表
被传递到递归过程(ByVal
或ByRef
)时,即使退出该过程,它也会留在内存中。该字符串在每次调用过程时都会保留在内存中,但在退出过程时会消失,因为它是通过ByVal
传递的。这两个物体是被区别对待的,还是我的理解有偏差
在form1_load
的末尾,为什么ht.count总是等于4,而不管它是通过byref还是byval传递的
我认为ht.count和str的长度应该始终相同,因为两者都是通过val传递的。为什么不是这样
谢谢你的帮助和理解!如果我需要说得更清楚,请告诉我
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim ht As New Hashtable
Dim i As Integer = 1
Dim str As String = ""
go(ht, str, i)
MsgBox("strLen = " & Len(str) & vbCrLf & "htCount = " & ht.Count)
End Sub
Private Sub go(ByVal ht As Hashtable, ByVal str As String, ByVal i As Integer)
str = str & "0"
ht.Add(i, 0)
i = i + 1
If i < 5 Then
go(ht, str, i)
End If
End Sub
Private Sub Form1\u Load(ByVal sender作为对象,ByVal e作为System.EventArgs)处理Me.Load
Dim ht作为新哈希表
尺寸i为整数=1
Dim str As String=“”
go(ht、str、i)
MsgBox(“strLen=”&Len(str)&vbCrLf&“htCount=”&ht.Count)
端接头
私有子go(ByVal ht作为哈希表,ByVal str作为字符串,ByVal i作为整数)
str=str&“0”
ht.Add(i,0)
i=i+1
如果我小于5,那么
go(ht、str、i)
如果结束
端接头
编辑:我不能回答我自己的问题,因为我是新来的,所以我也意识到:
对于任何想知道的人,我意识到我试图理解可变对象传递给过程byref或byval的方式。我添加了ht2,现在go过程只是将ht分配给ht2
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim ht As New Hashtable
Dim ht2 As New Hashtable
Dim i As Integer = 1
Dim str As String = ""
go(ht, str, i, ht2)
MsgBox("strLen = " & Len(str) & vbCrLf & "htCount = " & ht.Count & vbCrLf & "ht2Count = " & ht2.Count)
End Sub
Private Sub go(ByVal ht As Hashtable, ByVal str As String, ByVal i As Integer, ByVal ht2 As Hashtable)
str = str & "0"
ht.Add(i, 0)
ht2 = ht
i = i + 1
If i < 5 Then
go(ht, str, i, ht2)
End If
End Sub
Private Sub Form1\u Load(ByVal sender作为对象,ByVal e作为System.EventArgs)处理Me.Load
Dim ht作为新哈希表
Dim ht2作为新哈希表
尺寸i为整数=1
Dim str As String=“”
go(ht、str、i、ht2)
MsgBox(“strLen=“&Len(str)&vbCrLf&”htCount=“&ht.Count&vbCrLf&”ht2Count=“&ht2.Count”)
端接头
私有子go(ByVal ht作为哈希表,ByVal str作为字符串,ByVal i作为整数,ByVal ht2作为哈希表)
str=str&“0”
ht.Add(i,0)
ht2=ht
i=i+1
如果我小于5,那么
go(ht、str、i、ht2)
如果结束
端接头
现在ht2依赖于它传递给过程的方式,ht2.count应该始终与str的长度相同。这也帮助我理解:
String
s和哈希表
s都是引用类型。您的案例中的主要区别在于它们的可变性
String
s是不可变的。每当您“编辑”一个字符串时,您都在堆上的一个新内存位置创建一个新的字符串
HashTable
s是可变的,因此当您添加/删除一个元素时,您并不是在构建一个全新的HashTable
。它保持在堆上以前的位置。这两个对象没有区别对待。问题是你如何使用它们。字符串连接不会更改字符串,它只返回一个带有连接值的新字符串。但是,Hashtable.Add()会更改对象
ByRef的事情更难理解。字符串的ByRef的行为与预期的一样,因为您正在更改所引用的对象。但是,哈希表的ByRef的行为与您期望的不一样,因为您正在向该表发送消息。Add告诉该表:将其添加到集合中。因此,您总是处理同一个对象
因此,这里的区别在于,您正在创建字符串的多个副本并更改引用,但您只有一个哈希表副本并更改其内容。谢谢!这使我走上了正确的道路。我意识到我试图将哈希表的易变性与它传递给过程的方式联系起来。谢谢!这就是我需要的。另外,我刚刚意识到,如果我希望哈希表的返回依赖于它传递给过程的方式,那么我应该在递归函数中构建一个新的哈希表,并返回这个新的哈希表。