83 votes

Quelle est l'utilité de System.String.Copy dans .NET ?

Je crains que ce ne soit une question très bête, mais quelque chose doit m'échapper.

Pourquoi voudrait-on utiliser String.Copy(string) ?

La documentation indique que la méthode

Crée une nouvelle instance de String avec la même valeur que la chaîne spécifiée.

Puisque les chaînes sont immuables dans .NET, je ne suis pas sûr de l'avantage d'utiliser cette méthode, car je pensais que

 string copy = String.Copy(otherString);

semblerait, à toutes fins pratiques, donner le même résultat que

 string copy = otherString;

C'est-à-dire, à l'exception de la comptabilité interne qui se passe, et le fait que la copie n'est pas ReferenceEquals à otherString, il n'y a pas de différences observables - String étant une classe immuable dont l'égalité est basée sur la valeur et non sur l'identité. (Merci à @Andrew Hare d'avoir signalé que ma formulation originale n'était pas assez précise pour indiquer que je réalisais qu'il y avait une différence entre Copy et non, mais s'inquiétait de la perception d'un manque d'engagement de la part de l'UE. utile différence.)

Bien sûr, lorsque l'on passe un null la copie envoie un ArgumentNullException et la "nouvelle instance" pourrait consommer plus de mémoire. Ce dernier point ne semble pas être un avantage, et je ne suis pas sûr que la vérification de la nullité soit un bonus suffisamment important pour justifier une méthode Copy entière.

Merci.

1 votes

Les questions idiotes ont beaucoup de votes,

56voto

tvanfosson Points 268301

Avec String.Copy vous allouez en fait une nouvelle mémoire et copiez les caractères d'une chaîne de caractères à l'autre ; vous obtenez une instance complètement nouvelle, alors que les deux variables sont la même instance. Cela peut avoir de l'importance si vous utilisez la chaîne avec du code non géré qui traite directement les emplacements de mémoire et peut modifier la chaîne.

0 votes

C'est ce que je pensais. Ce serait effrayant si le texte de toute l'application changeait de façon aléatoire...

2 votes

Bien que ce soit la première chose qui me soit venue à l'esprit, cela ressemble à un bogue qui attend de se produire - si vous effectuez une interopérabilité avec du code non géré qui modifie une chaîne, vous devriez probablement utiliser un StringBuilder à la place.

4 votes

Cela ressemble à un modèle de bogue si vous avez essayé de modifier un objet immuable.

28voto

Kennet Belenky Points 2026

Voici une pièce du puzzle. Elle n'explique pas pourquoi vous voudriez le faire, mais elle permet d'expliquer une différence fonctionnelle.

Si vous épinglez la chaîne à l'aide de l'option fixed le contenu serait mutable. De mémoire, je n'arrive pas à penser à une situation dans laquelle vous voudriez faire cela, mais c'est possible.

string original = "Hello World";
string refCopy = original;
string deepCopy = String.Copy(original);

fixed(char* pStr = original)
{
   *pStr = 'J';
}

Console.WriteLine(original);
Console.WriteLine(refCopy);
Console.WriteLine(deepCopy);

Sortie :

Jello World
Jello World
Hello World

1 votes

Ça, c'est minable et horrible. +1 pour l'exemple.

0 votes

réponse fantastique.

0 votes

Il ne s'agit pas d'une erreur, mais d'un abus typique. Par exemple, pour des raisons de sécurité, lorsque vous utilisez des SecureString ou que vous stockez brièvement des données sensibles en mémoire, vous pouvez vouloir effacer le contenu de la chaîne en mémoire plutôt que d'attendre la collecte des déchets. Il est beaucoup plus difficile de vider le contenu de la mémoire et d'attraper les données qui restent là en attendant d'être nettoyées si vous les effacez immédiatement lorsqu'elles ne sont plus nécessaires.

21voto

Andrew Hare Points 159332

String.Copy renvoie un nouveau String et ne donne pas les mêmes résultats que

String copy = otherString;

Essayez ça :

using System;

class Program
{
    static void Main()
    {
        String test = "test";
        String test2 = test;
        String test3 = String.Copy(test);

        Console.WriteLine(Object.ReferenceEquals(test, test2));
        Console.WriteLine(Object.ReferenceEquals(test, test3));

        Console.ReadLine();
    }
}

Lorsque vous définissez test2 = test ces références renvoient au même String . Le site Copy renvoie un nouveau String qui a la même contenu mais comme un objet différent sur le tas.


Edit : Il y a beaucoup de gens qui sont assez contrariés que je n'ai pas répondu à la question de l'OP. Je pense avoir répondu à la question en corrigeant une prémisse incorrecte dans la question elle-même. Voici une question et une réponse analogues (même si elles sont trop simplifiées) qui, je l'espère, illustreront mon propos :

Question :

J'ai observé que ma voiture a deux portes, une de chaque côté de la voiture. Je crois qu'il est vrai que quelle que soit la porte que j'utilise, je finirai par m'asseoir à la place du conducteur. À quoi sert l'autre porte ?

Réponse :

En fait, il n'est pas vrai que si vous utilisez l'une ou l'autre des portes, vous vous retrouverez à la place du conducteur. Si vous utilisez la porte du côté du conducteur, vous vous retrouverez sur le siège du conducteur et si vous utilisez la porte du côté du passager, vous vous retrouverez sur le siège du passager.

Dans cet exemple, on pourrait dire que la réponse n'en est pas vraiment une, puisque la question était "à quoi sert la porte du côté passager". Mais puisque cette question était entièrement basée sur une idée fausse du fonctionnement des portes, ne s'ensuit-il pas que la réfutation de la prémisse jettera une nouvelle lumière sur l'utilité de l'autre porte par déduction ?

0 votes

La question n'était pas "Qu'est-ce que ça fait ?" mais "Pourquoi je l'utiliserais ?".

0 votes

Je pense que le point était : "quelle est l'utilité de dupliquer des informations immuables ?" au lieu de les réutiliser.

0 votes

La question entière était basée sur la fausse prémisse que "string one = String.Copy(two) ;" et "string one = two ;" sont des déclarations équivalentes. J'ai simplement fait remarquer que l'affiche était incorrecte.

10voto

Gabe Points 49718

Une recherche rapide dans la BCL pour .NET 4.0 montre que la fonction string.Copy est appelée à une demi-douzaine d'endroits. Les utilisations se répartissent approximativement dans les catégories suivantes :

  1. Pour l'interopérabilité avec les fonctions natives qui peuvent endommager les chaînes qui leur sont passées. Si vous ne pouvez pas affecter la déclaration P/Invoke et que vous ne pouvez pas réparer la fonction appelée, string.Copy est le meilleur choix.

  2. Pour les situations où la chaîne est modifiée en cours de route pour des raisons de performance. Si vous devez convertir quelques caractères en minuscules dans une chaîne potentiellement longue, la seule façon de le faire sans copier la chaîne deux fois et créer des déchets supplémentaires est de la muter.

  3. Dans des endroits où cela ne semble pas nécessaire. Il est tout à fait possible que certains programmeurs soient plus habitués aux chaînes Java ou C++ et ne réalisent pas que copier une chaîne en C# est rarement utile.

8voto

Ian Ringrose Points 19115
string a = "abc";
string b = String.Copy(a);

Monitor.Enter(a); // not the same as Monitor.Enter(b);

Cependant

string c = "123";
string d = c;
Monitor.Enter(c); // the same as Monitor.Enter(d);

Quant à savoir si quelqu'un s'en soucie, je pense que c'est là pour être complet.


Aussi

StringBuilder sb = new StringBuilder(100);
sb.Append("abc");
string a = sb.ToString();
string b = String.Copy(a);

Je pense a occupera plus de RAM que b comme a pointe vers le tampon de taille 100 que le StringBuilder créé. (Regardez l'intérieur de la StringBuilder.ToString() méthode)


Je pense StringBuilder fait usage de String.Copy() et faisant partie du cadre .NET StringBuilder modifie le contenu de l'élément string . Donc un string n'est pas toujours immuable.

0 votes

Il n'est pas nécessaire pour StringBuilder de modifier une chaîne de caractères. En interne, il pourrait utiliser une Liste<char> qui croîtrait efficacement en taille, et ensuite la méthode ToString allouerait une chaîne de caractères à partir du contenu de la liste.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X