VB.NET:Si me pasa una Cadena ByVal en una función, pero no cambiar la cadena, tengo una o dos cadenas de caracteres en la memoria?
Pregunta
Sé que las cadenas son inmutables, por lo que el momento de cambiar una cadena de referencia del valor .NET hace una marca nueva cadena en el montón.
Pero, ¿qué si no cambio el valor de una cadena de referencia;más bien, simplemente pasarlo a una función ByVal
- ¿a esta operación de copia de la cadena de valor en el montón así?Mi inclinación es "no", pero me gustaría confirmar.
Por ejemplo:
Public Function IsStringHello(ByVal test As String) As Boolean
Return (String.Compare(test, "Hello") = 0)
End Function
Programa de llamada:
Dim myWord as String = "Blah"
Dim matchesHello as Boolean = IsStringHello(myWord)
Sé que pasa myWord
por el valor que hace una copia de la referencia a "Bla", pero ya que no he probado a cambiar la cadena en sí, sería hacer otra copia de la cadena en el montón?
Solución
Por cierto, el internamiento de cadenas no tiene ninguna relación con eso. La regla para pasar parámetros a funciones es la misma para todos los tipos de referencia (y realmente, todos los tipos), sin importar cómo se gestionen internamente.
La regla es simple y la ha indicado correctamente: pasar por valor copia la referencia , no el objetivo . Aquí no se copia ningún espacio de almacenamiento dinámico.
Otros consejos
No. todavía usa la copia de la referencia a " Blah " ;.
¿Qué te hace pensar que lo hará?
En una nota al margen, las cadenas están internados.
string s = "hello";
string t = "hello";
s & amp; Ambos se refieren a la misma cadena (porque está internada). Si modifica sot, creará una nueva cadena, entonces.
Pasar objetos ByVal crea una copia del puntero , no el objeto en sí. Aquí hay una demostración:
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 genera lo siguiente:
object.ReferenceEquals(original, other): True
Entonces, la cadena original y la cadena que pasamos por valor existen en la misma dirección en la dirección de memoria. No estás haciendo una copia de la cadena en sí.
Es corto, no. Pasa una referencia a la cadena. Solo una instancia de la cadena en sí.
cadena es un tipo de referencia. Si lo pasa por valor, lo que está pasando es el valor de la referencia.
La única forma de obtener otra copia en el montón sería cambiar el valor de la variable.
Una variable de tipo System.String
efectivamente tiene un "object-ID".Supongamos que Object #1934
es una cadena con los caracteres "Blah"
, y que decir Dim myWord As String = "Blah"
.El compilador, a continuación, almacenar Object #1934
en myWord
.Llamar IsStringHello(myWord)
sería entonces la causa de que la función sea llamada con su test
parámetro igual a Object #1934
.En tu ejemplo, habría dos variables de tipo System.String
en la memoria--myWord
y test
, y tanto se mantenga el contenido Object #1934
.