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 :
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
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.
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
Lors de l'instanciation de deux objets, la référence n'est pas égale. La méthode 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 Notez que le 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. Object.ReferenceEquals
ici . 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
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.
il renvoie akhil @Loocid
Vous avez deux objets chaîne, tous deux avec les mêmes données, mais ce sont toujours des objets séparés - c'est pourquoi
ReferenceEquals
renvoie false.Substring
ne regarde pas tout dans la mémoire pour essayer de trouver d'autres objets chaîne avec le même contenu.Double possible de C # .Equals (), .ReferenceEquals () et == opérateur a >
par ur instruction 1er objet.ReferenceEquals (s1, s2) devrait être faux alors pourquoi c'est vrai?
Ce serait vrai lorsque vous faites quelque chose comme ceci:
string s1 = 'Test'; chaîne s2 = s1;
Parce que s1 et s2 font référence au même objet, en raison du fonctionnement des littéraux de chaîne. Chaque fois que vous utilisez le même littéral de chaîne en C # dans un programme, vous vous retrouverez avec une référence au même objet. Ce n'est pas le cas lorsque vous appelez Substring.
Les littéraux de chaîne avec le même contenu sont considérés comme la même instance de chaîne que celle indiquée au bas de cette page: 2.4.4.5 Littéraux de chaîne
Vous pouvez voir la partie sous-chaîne comme
s4 = new String ("akhil")
, qui a créé une autre instanceConsultez également la documentation, docs.microsoft .com / fr-fr / dotnet / api /…