VB.NET:Se eu passar uma Seqüência de caracteres de ByVal para uma função, mas não altere a seqüência de caracteres, tenho uma ou duas seqüências de caracteres na memória?
Pergunta
Eu sei que strings são imutáveis, assim, o minuto em que você alterar a seqüência de caracteres de referência de valor .NET faz uma nova seqüência de caracteres no heap.
Mas o que se não mudança o valor de uma cadeia de referência;em vez disso, você simplesmente passá-lo para uma função ByVal
-- esta operação de copiar a cadeia de valor na pilha bem?A minha inclinação é "não", mas eu gostaria de confirmar.
Por exemplo:
Public Function IsStringHello(ByVal test As String) As Boolean
Return (String.Compare(test, "Hello") = 0)
End Function
Chamada do programa:
Dim myWord as String = "Blah"
Dim matchesHello as Boolean = IsStringHello(myWord)
Eu sei passando myWord
por este valor, faz uma cópia do referência a "Blá", mas desde que eu não tentei alterar a seqüência de si mesmo, seria fazer outra cópia da seqüência de caracteres no heap?
Solução
A propósito, a string está completamente relacionada a isso. A regra para a aprovação de parâmetros para funções é a mesma para todos os tipos de referência (e realmente, todos os tipos), não importa como eles sejam gerenciados internamente.
A regra é simples e você declarou corretamente: passe por valor cópias referência, não o alvo. Nenhum espaço de heap é copiado aqui.
Outras dicas
Não. Ele ainda usa o cópia da referência para o "blá".
O que te faz pensar, vai?
Em uma nota lateral, a string está internada.
string s = "hello";
string t = "hello";
S&T se referem à mesma string (porque está internada). Se você modificar s ou t, ele criará uma nova string e depois.
Passando objetos Byval cria uma cópia do ponteiro, não o próprio objeto. Aqui está uma demonstração:
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
Este programa gera o seguinte:
object.ReferenceEquals(original, other): True
Portanto, a string original e a string que passamos pelo valor existem no mesmo endereço no endereço da memória. Você não está fazendo uma cópia da própria string.
É curto, não. Ele passa um ref para a string. Apenas uma instância da própria string.
String é um tipo de referência. Se você passar por valor, o que você está passando é o valor da referência.
A única maneira de obter outra cópia na pilha seria alterar o valor da variável.
Uma variável do tipo System.String
efetivamente, detém um "objeto de IDENTIFICAÇÃO".Suponha que Object #1934
é uma cadeia de caracteres com caracteres "Blah"
, e você dizer Dim myWord As String = "Blah"
.O compilador vai armazenar Object #1934
em myWord
.Chamar IsStringHello(myWord)
iria fazer com que a função seja chamada com o seu test
parâmetro igual a Object #1934
.No seu exemplo, haveria duas variáveis do tipo System.String
na memória--myWord
e test
, e ambos possuem o conteúdo Object #1934
.