3
votes

Est-ce que Substring crée une autre instance C #?

Je suis nouveau dans la chaîne C # Je suis confus à propos de

string s1 = "akhil";
string s2 = "akhil";

Console.WriteLine(object.ReferenceEquals(s1, s2)); //true
s2 = "akhil jain";
Console.WriteLine(object.ReferenceEquals(s1, s2)); //false
//Console.WriteLine(s1 == s2);
//Console.WriteLine(s1.Equals(s2));

string s3 = "akhil";
//1".Substring(0, 5);
Console.WriteLine(s3+" " +s1);
Console.WriteLine(object.ReferenceEquals(s1,s3)); //true


string s4 = "akhil1".Substring(0, 5);
Console.WriteLine(object.ReferenceEquals(s1, s4)); //confusion false why as s4 data is same as s1

Je lisais un article qui dit ReferenceEquals vérifier si c'est la même instance ou non dans le programme Je vérifie si object.ReferenceEquals (s1, s4) même s'ils pointent vers les mêmes données, pourquoi il est faux?

 Object.referenceEquals 


3 Réponses :


2
votes

Les références sont les mêmes car un littéral de chaîne est interné , Substring renvoie une nouvelle chaîne et une nouvelle référence, ce n'est pas le cas essayez de deviner vos paramètres et vérifiez le pool de stagiaires

String.Intern (String ) Méthode

Le Common Language Runtime préserve le stockage des chaînes en maintenant un table, appelée pool interne, qui contient une seule référence à chaque chaîne littérale unique déclarée ou créée par programme dans votre programme. Par conséquent, une instance d'une chaîne littérale avec un une valeur particulière n'existe qu'une seule fois dans le système.

Par exemple, si vous affectez la même chaîne littérale à plusieurs variables, le moteur d'exécution récupère la même référence au littéral chaîne du pool interne et l'affecte à chaque variable .

Cependant, fait inutile 3454345.2 , depuis .Net 2 , vous avez pu le désactiver pour diverses raisons que vous pourriez avoir

Énumération

NoStringInterning Marque un assembly comme ne nécessitant pas d'internement de chaîne littérale. Dans un domaine d'application, le commun le moteur d'exécution du langage crée un objet chaîne pour chaque chaîne unique littéral, plutôt que de faire plusieurs copies. Ce comportement, appelé string interning, nécessite en interne la création de tables auxiliaires qui consomme des ressources mémoire.


2 commentaires

y a-t-il une autre méthode qui créera une nouvelle instance en plus de la sous-chaîne?


@ Deepak Jain Chaque méthode, sauf si vous utilisez un littéral, ou la méthode interne, ou le code IL interne



0
votes

Lors de l'instanciation de deux objets, la référence n'est pas égale. La méthode Object.ReferenceEquals renvoie donc false. Cependant, les chaînes sont un cas très particulier. Si vous déclarez une chaîne dans le code, le CLR la conserve dans une table. Cela s'appelle le pool de stagiaires a>. Cela provoque deux chaînes qui ont été instanciées avec la même valeur pour référencer le même objet en mémoire. Cela fera que Object.ReferenceEquals retourne true.

Lorsqu'une chaîne a été formée par une opération dans votre code, elle n'est pas automatiquement internée dans le pool. Et par conséquent, il a une référence différente, bien que le contenu de la chaîne puisse être le même. Ceci est également expliqué dans les remarques de la documentation de Object.ReferenceEquals ici .

Notez que le String.Equals ( ) renvoie true. En C #, vous pouvez également utiliser l'opérateur '==' sur les chaînes. Consultez votre code ajusté ci-dessous.

string s1 = "akhil";
string s2 = "akhil";

Console.WriteLine(s1.Equals(s2)); //true
s2 = "akhil jain";
Console.WriteLine(s1.Equals(s2)); //false

string s3 = "akhil";
Console.WriteLine(s3 + " " + s1);
Console.WriteLine(s1.Equals(s3)); //true

string s4 = "akhil1".Substring(0, 5);
Console.WriteLine(s1.Equals(s4)); //this now returns true as well
Console.WriteLine(s1 == s4);      //so does this


0 commentaires

0
votes

La valeur de object.ReferenceEquals est false car elle vérifie si les deux références pointent vers le même objet. ReferenceEquals ne vérifie pas l'égalité des données, mais si les deux objets occupent la même adresse mémoire.

Comme TheGeneral l'a déjà mentionné, les littéraux de chaîne sont internés et stockés dans une table appelée pool interne. C'est pour stocker efficacement les objets chaîne.

Lorsqu'un littéral chaîne est assigné à plusieurs variables, elles pointent vers la même adresse dans le pool interne. Par conséquent, vous obtenez true pour object.ReferenceEquals. Mais lorsque vous comparez cela avec une sous-chaîne, un nouvel objet a été créé dans la mémoire. Cela donne un faux lorsque la référence est comparée car ce sont deux objets différents occupant des emplacements mémoire différents.

Toutes les chaînes créées dynamiquement, ou lues depuis une source externe ne sont pas automatiquement internées.

Si vous essayez ce qui suit, vous obtiendrez true pour object.ReferenceEquals:

int a = 10;
int b = a;
Console.WriteLine(ReferenceEquals(a, b)); //false

Vous pouvez vérifier avec les types de données Primitive que ReferenceEquals renvoie false même lorsqu'une variable est affectée à un autre.

Console.WriteLine(object.ReferenceEquals(s1, string.Intern(s4)));

C'est parce que chaque type primitif est stocké séparément.


0 commentaires