【问题标题】:VB.Net passing Hashtable and string to recursive procedureVB.Net 将 Hashtable 和字符串传递给递归过程
【发布时间】:2013-06-25 05:32:41
【问题描述】:

这里我有一个递归过程。似乎无论何时将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

【问题讨论】:

    标签: vb.net string recursion hashtable


    【解决方案1】:

    Strings 和 HashTables 都是引用类型。您的情况的主要区别在于它们的可变性。

    Strings 是不可变的。每当您“编辑”String 时,都会在堆上的新内存位置创建一个新的。

    HashTables 是可变的,所以当你添加/删除一个元素时,你并没有构建一个全新的HashTable。它在堆上保持原来的位置。

    【讨论】:

    • 谢谢!这确实使我走上了正轨。我意识到我试图将哈希表的可变性与其传递给过程的方式联系起来。
    【解决方案2】:

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

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

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

    【讨论】:

    • 谢谢!这就是我需要的。另外,我刚刚意识到,如果我希望哈希表的返回取决于它传递给过程的方式,那么我应该在递归函数中构建一个新的哈希表并返回这个新的哈希表。
    猜你喜欢
    • 2013-06-27
    • 1970-01-01
    • 2017-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-13
    相关资源
    最近更新 更多