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?
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 .
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
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 :)
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.
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
}
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)
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 dansString.Empty
?
référence: String.Empty
vs ""
de la Chaîne.Vide ne crée pas un objet alors que le "ne". La différence, comme indiqué ici , est insignifiante, cependant.
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.
ça n'a pas d'importance!
Quelques-delà de la discussion de ce:
http://www.codinghorror.com/blog/archives/000185.html
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/
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.
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.
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
}
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.