1

在这里,我有一个递归过程。似乎只要将Hashtable传递给递归过程(ByValByRef),即使退出过程,它也会保留在内存中。该字符串在过程的每次调用时都保留在内存中,但在退出过程时它会消失,因为它被传递了ByVal。这两个对象的处理方式是否不同,还是我的理解不正确?

结束时form1_load,为什么ht.count不管是byref还是byval传递的总是等于4?

我在想 ht.count 和 str 的长度应该总是相同的,因为两者都是通过 byval 传递的。为什么这不是真的?

感谢您的帮助并试图理解!让我知道我是否需要更清楚。

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

编辑:我无法回答自己的问题,因为我是新手,所以这也是我意识到的:

对于任何想知道的人,我意识到我试图理解可变对象传递给过程 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

现在 ht2 取决于它传递给过程的方式,并且 ht2.count 应该始终与 str 的长度相同。此外,这有助于我理解:http ://en.wikipedia.org/wiki/Reference_type

4

2 回答 2

0

Strings and HashTables are both reference types. The main difference in your case is their mutability.

Strings are immutable. Whenever you "edit" a String, you are creating a new one, in a new memory location on the heap.

HashTables are mutable, so when you add/remove an element, you aren't building a whole new HashTable. It stays where it was before on the heap.

于 2013-06-27T16:15:32.557 回答
-1

这两个对象没有区别对待。问题是你如何使用它们。字符串连接不会改变字符串,它只是返回一个带有连接值的新字符串。然而,Hashtable.Add() 确实改变了对象。

ByRef 的事情有点难以理解。String 的 ByRef 的行为与您预期的一样,因为您正在更改所引用的对象。但是,Hashtable 的 ByRef 的行为并不像您预期​​的那样,因为您正在向表发送消息。Hashtable.Add 告诉表格:将其添加到您的集合中。因此,您总是在处理同一个对象。

因此,这里的区别在于您创建了多个 String 副本并更改了引用,但您只有一个 Hashtable 副本并更改了其内容。

于 2013-06-27T17:24:36.847 回答