ВБ.НЕТ:Если я передаю String ByVal в функцию, но не меняю строку, останется ли у меня в памяти одна или две строки?
Вопрос
Я знаю, что строки неизменяемы, поэтому в ту минуту, когда вы меняете значение ссылки на строку, .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
по значению делает копию ссылка на «Бла», но поскольку я не пытался изменить саму строку, создаст ли это еще одну копию строки в куче?
Решение
Кстати, интернирование строк к этому совершенно не относится.Правило передачи параметров в функции одинаково для всех ссылочных типов (и фактически для всех типов), независимо от того, как они управляются внутри.
Правило простое, и вы правильно его сформулировали:передача по значению копирует ссылка, не цель.Здесь не копируется пространство кучи.
Другие советы
Нет.он по-прежнему использует копия справки на "Бла".
Что заставляет вас думать, что так и будет?
Кстати, строки интернированы.
string s = "hello";
string t = "hello";
s и t относятся к одной и той же строке (поскольку она интернирована).Если вы измените s или t, тогда будет создана новая строка.
Передача объектов 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
Таким образом, исходная строка и строка, которую мы передали по значению, существуют по одному и тому же адресу в памяти.Вы не делаете копию самой строки.
Коротко, нет.Он передает ссылку на строку.Только один экземпляр самой строки.
строка является ссылочным типом.Если вы передаете его по значению, вы передаете значение ссылки.
Единственный способ получить еще одну копию в куче — это изменить значение переменной.
Переменная типа System.String
эффективно содержит «идентификатор объекта».Предположим, что Object #1934
это строка с символами "Blah"
, и ты говоришь Dim myWord As String = "Blah"
.Затем компилятор сохранит Object #1934
в myWord
.Вызов IsStringHello(myWord)
затем приведет к вызову этой функции с ее test
параметр, равный Object #1934
.В вашем примере будет две переменные типа System.String
в памяти--myWord
и test
, и оба будут содержать содержимое Object #1934
.