VB.NET: Si je passe une chaîne ByVal à une fonction sans changer de chaîne, ai-je une ou deux chaînes en mémoire?
Question
Je sais que les chaînes de caractères sont immuables. Dès que vous modifiez la valeur d'une référence de chaîne, NET crée une nouvelle chaîne sur le tas.
Mais que se passe-t-il si vous ne changez pas la valeur d'une référence de chaîne; vous le transmettez simplement à une fonction ByVal
- cette opération copie-t-elle également la valeur de chaîne sur le tas? Mon inclination est & "Non, &"; mais je voudrais confirmer.
Par exemple:
Public Function IsStringHello(ByVal test As String) As Boolean
Return (String.Compare(test, "Hello") = 0)
End Function
Programme d’appel:
Dim myWord as String = "Blah"
Dim matchesHello as Boolean = IsStringHello(myWord)
Je sais que passer myWord
par valeur crée une copie de la référence en & "Blah &"; mais je n'ai pas essayé de modifier la chaîne elle-même. fait-il une autre copie de la chaîne sur le tas?
La solution
Au fait, l'internement de chaînes n'a aucun lien avec cela. La règle de transmission des paramètres aux fonctions est la même pour tous les types de référence (et en réalité pour tous les types), quelle que soit la manière dont ils sont gérés en interne.
La règle est simple et vous l'avez énoncée correctement: passer par valeur copie la référence , pas la cible . Aucun espace de pile n'est copié ici.
Autres conseils
Non. il utilise toujours la copie de la référence au & "Blah &";
.
Qu'est-ce qui vous fait penser, ça va?
Sur une note latérale, les chaînes sont internées.
string s = "hello";
string t = "hello";
s & amp; t les deux font référence à la même chaîne (car elle est internée). Si vous modifiez s ou t, une nouvelle chaîne sera créée, puis.
Passer des objets ByVal crée une copie du pointeur , pas de l'objet lui-même. Voici une démonstration:
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
Ce programme génère les éléments suivants:
object.ReferenceEquals(original, other): True
Ainsi, la chaîne d'origine et la chaîne que nous avons passée par valeur existent à la même adresse dans l'adresse mémoire. Vous ne faites pas de copie de la chaîne elle-même.
Est court, non. Il passe une référence à la chaîne. Une seule instance de la chaîne elle-même.
chaîne est un type de référence. Si vous le transmettez par valeur, ce que vous transmettez est la valeur de la référence.
La seule façon d'obtenir une autre copie sur le tas serait de changer la valeur de la variable.
Une variable de type System.String
contient effectivement un & "; ID d'objet &"; Supposons que Object #1934
est une chaîne avec les caractères "Blah"
et que vous dites Dim myWord As String = "Blah"
. Le compilateur stockera ensuite myWord
dans IsStringHello(myWord)
. L'appel de test
entraîne alors l'appel de cette fonction avec son paramètre <=> égal à <=>. Dans votre exemple, il y aurait deux variables de type <=> en mémoire - <=> et <=>, et les deux contiendraient le contenu <=>.