VB.NET: se passo una stringa ByVal in una funzione ma non cambio la stringa, ho una o due stringhe in memoria?
Domanda
So che le stringhe sono immutabili, quindi nel momento in cui si modifica il valore di un riferimento di stringa. NET crea una nuova stringa nell'heap.
Ma cosa succede se non cambi il valore di un riferimento di stringa; piuttosto, lo passi semplicemente in una funzione ByVal
- questa operazione copia anche il valore della stringa nell'heap? La mia inclinazione è & Quot; no, & Quot; ma vorrei confermare.
Ad esempio:
Public Function IsStringHello(ByVal test As String) As Boolean
Return (String.Compare(test, "Hello") = 0)
End Function
Programma di chiamata:
Dim myWord as String = "Blah"
Dim matchesHello as Boolean = IsStringHello(myWord)
So che passare myWord
in base al valore crea una copia del riferimento in " Blah " ;, ma poiché non ho provato a cambiare la stringa stessa, crea un'altra copia della stringa nell'heap?
Soluzione
A proposito, il string interning è completamente estraneo a quello. La regola per passare i parametri alle funzioni è la stessa per tutti i tipi di riferimento (e davvero, per tutti i tipi), indipendentemente da come sono gestiti internamente.
La regola è semplice e l'hai dichiarata correttamente: passa per valore copia il riferimento , non il target . Nessuno spazio heap viene copiato qui.
Altri suggerimenti
No. utilizza ancora la copia del riferimento nella " Blah " ;.
Cosa ti fa pensare, lo farà?
In una nota a margine, le stringhe sono internate.
string s = "hello";
string t = "hello";
s & amp; t si riferiscono entrambi alla stessa stringa (perché è internata). Se modifichi s o t, creerà una nuova stringa, quindi.
Passaggio di oggetti ByVal crea una copia del puntatore , non dell'oggetto stesso. Ecco una dimostrazione:
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
Questo programma genera quanto segue:
object.ReferenceEquals(original, other): True
Quindi, la stringa originale e la stringa che abbiamo passato per valore esistono allo stesso indirizzo nell'indirizzo di memoria. Non stai facendo una copia della stringa stessa.
È breve, no. Passa un riferimento alla stringa. Solo un'istanza della stringa stessa.
stringa è un tipo di riferimento. Se lo passi per valore, quello che stai passando è il valore del riferimento.
L'unico modo per ottenere un'altra copia sull'heap sarebbe quello di modificare il valore della variabile.
Una variabile di tipo System.String
contiene effettivamente un " ID oggetto " ;. Supponi che Object #1934
sia una stringa con i caratteri "Blah"
e dici Dim myWord As String = "Blah"
. Il compilatore memorizzerà quindi myWord
in IsStringHello(myWord)
. Chiamare test
causerebbe quindi la chiamata a quella funzione con il suo parametro <=> uguale a <=>. Nel tuo esempio, ci sarebbero due variabili di tipo <=> in memoria - <=> e <=> ed entrambe conserverebbero il contenuto <=>.