VB.NET:如果我将 String ByVal 传递给函数但不更改该字符串,那么内存中是否有一个或两个字符串?

发布于 2024-07-25 12:22:35 字数 576 浏览 6 评论 0原文

我知道字符串是不可变的,因此一旦更改字符串引用的值,.NET 就会在堆上创建一个全新的字符串。

但是,如果您不更改字符串引用的值怎么办? 相反,您只需将其传递给函数 ByVal ——此操作是否也会复制堆上的字符串值? 我的倾向是“不”,但我想确认一下。

例如:

Public Function IsStringHello(ByVal test As String) As Boolean 
  Return (String.Compare(test, "Hello") = 0)    
End Function

调用程序:

Dim myWord as String = "Blah"
Dim matchesHello as Boolean = IsStringHello(myWord)

我知道按值传递 myWord 会复制“Blah”的引用,但由于我没有尝试更改字符串本身,因此它会在堆上制作另一个字符串副本吗?

I know strings are immutable, so the minute you change a string reference's value .NET makes a brand new string on the heap.

But what if you don't change the value of a string reference; rather, you simply pass it into a function ByVal -- does this operation copy the string value on the heap as well? My inclination is "no," but I'd like to confirm.

For example:

Public Function IsStringHello(ByVal test As String) As Boolean 
  Return (String.Compare(test, "Hello") = 0)    
End Function

Calling program:

Dim myWord as String = "Blah"
Dim matchesHello as Boolean = IsStringHello(myWord)

I know passing myWord by value makes a copy of the reference to "Blah", but since I have not tried to change the string itself, would it make another copy of the string on the heap?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

裸钻 2024-08-01 12:22:35

顺便说一句,字符串驻留与此完全无关。 对于所有引用类型(实际上是所有类型),将参数传递给函数的规则都是相同的,无论它们内部如何管理。

规则很简单,并且您已经正确表述了:按值传递会复制引用,而不是目标。 这里没有复制堆空间。

By the way, string interning is completely unrelated to that. The rule for passing parameters to functions is the same for all reference types (and really, all types), no matter how they are managed internally.

The rule is simple and you have stated it correctly: pass by value copies the reference, not the target. No heap space is copied here.

为你拒绝所有暧昧 2024-08-01 12:22:35

不,它仍然使用“Blah”的引用副本
是什么让你认为它会发生?

附带说明一下,字符串是被拘留的。

string s = "hello";
string t = "hello";

和 两者都引用相同的字符串(因为它是内部的)。 如果修改 s 或 t,它将创建一个新字符串。

No. it still uses the copy of the reference to the "Blah".
What makes you think, it will?

On a side note, string are interned.

string s = "hello";
string t = "hello";

s & t both refer to the same string (because it is interned). If you modify s or t, it will create a new string, then.

最丧也最甜 2024-08-01 12:22:35

传递对象 ByVal 会创建指针的副本,而不是对象本身。 这是一个演示:

Module Module1
    Dim original As String = "Hello world"

    Sub PassByReferenceTest(ByVal other As String)
        Console.WriteLine("object.ReferenceEquals(original, other): {0}", _
            Object.ReferenceEquals(original, other))
    End Sub

    Sub Main()
        PassByReferenceTest(original)
        Console.ReadKey(True)
    End Sub
End Module

该程序输出以下内容:

object.ReferenceEquals(original, other): True

因此,原始字符串和我们按值传递的字符串存在于内存地址中的同一地址。 您没有复制字符串本身。

Passing objects ByVal creates a copy of the pointer, not the object itself. Here's a demonstration:

Module Module1
    Dim original As String = "Hello world"

    Sub PassByReferenceTest(ByVal other As String)
        Console.WriteLine("object.ReferenceEquals(original, other): {0}", _
            Object.ReferenceEquals(original, other))
    End Sub

    Sub Main()
        PassByReferenceTest(original)
        Console.ReadKey(True)
    End Sub
End Module

This program outputs the following:

object.ReferenceEquals(original, other): True

So, the original string and the string we passed by value exist at the same address in memory address. You're not making a copy of the string itself.

合约呢 2024-08-01 12:22:35

很短,没有。 它将引用传递给字符串。 字符串本身只有一个实例。

Is short, no. It passes a ref to the string. Only one instance of the string itself.

○闲身 2024-08-01 12:22:35

字符串是引用类型。 如果按值传递,则传递的是引用的值。

在堆上获得另一个副本的唯一方法是更改​​变量的值。

string is a reference type. If you pass it by value, what you are passing is the value of the reference.

The only way you'd get another copy on the heap would be to change the variable's value.

薄荷→糖丶微凉 2024-08-01 12:22:35

System.String 类型的变量有效地保存一个“对象 ID”。 假设 Object #1934 是一个包含字符 "Blah" 的字符串,并且您说 Dim myWord As String = "Blah"。 然后,编译器会将 Object #1934 存储到 myWord 中。 调用 IsStringHello(myWord) 将导致调用该函数,其 test 参数等于 Object #1934。 在您的示例中,内存中有两个 System.String 类型的变量 - myWordtest,并且两者都将保存内容 <代码>对象#1934。

A variable of type System.String effectively holds an "object-ID". Suppose that Object #1934 is a string with the characters "Blah", and you say Dim myWord As String = "Blah". The compiler will then store Object #1934 into myWord. Calling IsStringHello(myWord) would then cause that function to be called with its test parameter equal to Object #1934. In your example, there would be two variables of type System.String in memory--myWord and test, and both would hold the content Object #1934.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文