Quelle est la différence entre la Chaîne.Vide et "" (chaîne vide)?

.NET, quelle est la différence entre String.Empty et "" , et sont-ils interchangeables, ou est-il une référence sous-jacent ou de la Localisation des questions autour de l'égalité que String.Empty permettra d'assurer, ne sont pas un problème?

252
demandé sur nawfal 2008-09-30 05:59:47

15 réponses

dans .NET avant la version 2.0, "" crée un objet tandis que string.Empty ne crée aucun objet ref , ce qui rend string.Empty plus efficace.

dans la version 2.0 et ultérieure de .NET, toutes les occurrences de "" se réfèrent à la même chaîne de caractères littérale, qui signifie "" est équivalent à .Empty , mais toujours pas aussi rapide que .Length == 0 .

.Length == 0 est le l'option la plus rapide, mais .Empty rend le code légèrement plus propre.

voir la spécification .NET pour plus d'information .

254
répondu Brian R. Bondy 2016-01-15 10:10:26

Quelle est la différence entre une corde.Vides et"", et sont-ils interchangeable

string.Empty est un champ en lecture seule alors que "" est une constante de temps de compilation. Les endroits où ils se comportent différemment sont:

valeur par défaut du paramètre C # 4.0 ou plus

void SomeMethod(int ID, string value = string.Empty)
// Error: Default parameter value for 'value' must be a compile-time constant
{
    //... implementation
}

Cas de l'expression de commutateur déclaration

string str = "";
switch(str)
{
    case string.Empty: // Error: A constant value is expected. 
        break;

    case "":
        break;

}

attribut arguments

[Example(String.Empty)]
// Error: An attribute argument must be a constant expression, typeof expression 
//        or array creation expression of an attribute parameter type
166
répondu Habib 2014-04-16 16:35:07

les réponses précédentes étaient correctes pour .NET 1.1 (regardez la date du message auquel elles renvoient: 2003). À partir de .NET 2.0 et plus tard, il n'y a essentiellement pas de différence. Le JIT finira par faire référence au même objet sur le tas de toute façon.

selon la spécification C#, section 2.4.4.5: http://msdn.microsoft.com/en-us/library/aa691090 (VS.71).aspx

chaque chaîne littérale n'est pas nécessairement résultat dans une nouvelle instance de chaîne. Lorsque deux ou plusieurs littérales de chaîne qui sont équivalentes selon l'opérateur d'égalité de chaîne (Section 7.9.7) apparaissent dans la même assemblée, ces littérales de chaîne se réfèrent à la même instance de chaîne.

Quelqu'un le mentionne même dans les commentaires du billet de Brad Abram

En résumé, le résultat pratique de "" par rapport à la Chaîne.Vide est nulle. Le JIT finira par s'en rendre compte.

I j'ai trouvé, personnellement, que le JIT est beaucoup plus intelligent que moi et j'essaie donc de ne pas devenir trop intelligent avec des optimisations de micro-compilateurs comme ça. Le JIT va se déployer pour les boucles (), supprimer le code redondant, les méthodes inline, etc mieux et à des moments plus appropriés que l'un ou L'autre I ou le compilateur C# pourrait jamais anticiper avant main. Laissez le JIT faire son travail :)

38
répondu chadmyers 2008-09-30 02:47:04

String.Empty est un champ readonly tandis que "" est un const . Cela signifie que vous ne pouvez pas utiliser String.Empty dans une instruction de commutation parce que ce n'est pas une constante.

33
répondu James Newton-King 2016-08-31 14:01:26

une autre différence est cette chaîne.Empty génère un code CIL plus grand. Alors que le code pour faire référence "" et chaîne.Empty est la même longueur, le compilateur n'optimise pas la concaténation des chaînes (voir de Eric Lippert "blog post ) pour les chaînes.Vide d'arguments. Les fonctions équivalentes suivantes

string foo()
{
    return "foo" + "";
}
string bar()
{
    return "bar" + string.Empty;
}

générer cette IL

.method private hidebysig instance string foo() cil managed
{
    .maxstack 8
    L_0000: ldstr "foo"
    L_0005: ret 
}
.method private hidebysig instance string bar() cil managed
{
    .maxstack 8
    L_0000: ldstr "bar"
    L_0005: ldsfld string [mscorlib]System.String::Empty
    L_000a: call string [mscorlib]System.String::Concat(string, string)
    L_000f: ret 
}
16
répondu Bruno Martinez 2013-06-30 02:07:51

les réponses ci-dessus sont techniquement correctes, mais ce que vous pouvez vraiment vouloir utiliser, pour une meilleure lisibilité du code et une moindre chance d'une exception est chaîne.IsNullOrEmpty (s)

13
répondu Eugene Katz 2008-09-30 04:06:11

utiliser String.Empty plutôt que "" .

C'est plus pour la vitesse que l'utilisation de la mémoire, mais c'est une astuce utile. Le "" est un littéral ainsi agira comme un littéral: sur la première utilisation, il est créé et pour les utilisations suivantes de référence est retourné. Un seul exemple de "" seront stockées en mémoire, peu importe combien de fois nous l'utiliser! Je ne vois aucun souvenir pénalités ici. le problème est que chaque fois que le "" est utilisé, une boucle de comparaison est exécutée pour vérifier si le "" est déjà dans la piscine des internes. de l'autre côté, String.Empty est une référence à un "" stocké dans la zone de mémoire .net Framework . String.Empty pointe vers la même adresse mémoire pour VB.NET et C# application. Alors pourquoi chercher une référence chaque fois que vous avez besoin "" quand avez-vous cette référence dans String.Empty ?

référence: String.Empty vs ""

8
répondu Mojtaba Rezaeian 2016-08-31 14:05:16

de la Chaîne.Vide ne crée pas un objet alors que le "ne". La différence, comme indiqué ici , est insignifiante, cependant.

6
répondu Esteban Araya 2008-09-30 02:02:48

Toutes les instances de "" sont les mêmes, interné chaîne littérale (ou qu'ils devraient être). Donc, vous ne serez vraiment pas jeter un nouvel objet sur le tas chaque fois que vous utilisez"", mais juste la création d'une référence à la même, objet interné. Cela dit, je préfère la chaîne.Vide. Je pense que ça rend le code plus lisible.

6
répondu Jason Jackson 2008-09-30 02:08:05

j'ai tendance à utiliser String.Empty plutôt que "" pour une raison simple, mais pas évidente: "" et "" ne sont pas les mêmes, le premier a en fait 16 caractères de largeur zéro en elle. Évidemment, aucun développeur compétent ne va mettre des caractères de largeur zéro dans leur code, mais s'ils y entrent, ça peut être un cauchemar d'entretien.

Notes:

  • j'ai utilisé U+FEFF dans cet exemple.

  • Je ne suis pas sûr si C'est le cas va manger ces caractères, mais essayez-le vous-même avec l'un des nombreux caractères de largeur zéro

  • c'est seulement grâce à https://codegolf.stackexchange.com/

5
répondu The_Lone_Devil 2015-11-25 11:42:56
string mystring = "";
ldstr ""

ldstr pousse une nouvelle référence d'objet à un littéral de chaîne stockée dans les métadonnées.

string mystring = String.Empty;
ldsfld string [mscorlib]System.String::Empty

ldsfld pousse la valeur d'un champ statique sur l'évaluation de la pile

j'ai tendance à utiliser String.Empty au lieu de "" parce que IMHO c'est plus clair et moins VB-ish.

4
répondu Salvuccino 2015-04-17 16:56:04

venant à cela d'un point de vue de cadre D'entité: EF versions 6.1.3 semble traiter chaîne.Vide et "" différemment lors de la validation.

de la chaîne.Empty est traité comme une valeur nulle pour les besoins de la validation et lancera une erreur de validation si elle est utilisée sur un champ requis (attribué); où as "" passera la validation et ne lancera pas l'erreur.

ce problème peut être résolu dans EF 7+. Référence: - https://github.com/aspnet/EntityFramework/issues/2610 ).

Edition: [Obligatoire(AllowEmptyStrings = true)] pour résoudre ce problème, permettant à la chaîne.Vide pour valider.

2
répondu Anthony 2017-03-09 12:07:07

Depuis String.Vide n'est pas une constante de compilation vous ne pouvez pas l'utiliser comme valeur par défaut dans la définition de fonction.

public void test(int i=0,string s="")
    {
      // Function Body
    }
1
répondu user3830433 2017-03-14 07:11:07

tout le monde ici a donné une bonne clarification théorique. J'ai eu le même doute. J'ai donc essayé une base de codage. Et j'ai trouvé une différence. Voici la différence.

string str=null;
Console.WriteLine(str.Length);  // Exception(NullRefernceException) for pointing to null reference. 


string str = string.Empty;
Console.WriteLine(str.Length);  // 0

donc il semble" Null "signifie absolument null &" chaîne.Vide" signifie qu'Elle contient une sorte de valeur, mais il est vide.

-4
répondu Deepak 2016-01-21 16:19:45