Was ist in .NET der Unterschied zwischen String.Empty
und ""
und sind sie austauschbar, oder gibt es einige zugrunde liegende Referenz- oder Lokalisierungsprobleme im Zusammenhang mit der Gleichstellung, String.Empty
die sicherstellen, dass sie kein Problem darstellen?
.net
double-quotes
string
Johnc
quelle
quelle
string.Empty
und was der Grund dafür war, es alsreadonly
statt zu deklarierenconst
.Antworten:
In .NET vor Version 2.0,
""
erstellt ein Objekt , währendstring.Empty
kein Objekt erstellt ref , was machtstring.Empty
effizienter.In Version 2.0 und höher von .NET
""
beziehen sich alle Vorkommen von auf dasselbe Zeichenfolgenliteral, was bedeutet, dass""
es äquivalent zu.Empty
, aber immer noch nicht so schnell ist wie.Length == 0
..Length == 0
ist die schnellste Option,.Empty
sorgt aber für etwas saubereren Code.Weitere Informationen finden Sie in der .NET-Spezifikation .
quelle
string.IsNullOrEmpty( stringVar )
.string.Empty
ist ein schreibgeschütztes Feld, während""
es sich um eine Kompilierungszeitkonstante handelt. Orte, an denen sie sich anders verhalten, sind:Standardparameterwert in C # 4.0 oder höher
Groß- / Kleinschreibung in der switch-Anweisung
Attributargumente
quelle
String.Empty
in den meisten Fällen als Argument übergeben können. Sie haben Recht, dass alle Beispiele dies zeigen,you simply can't put a (run-time) "value" into (compile-time) metadata
und das ist es, was die Beispiele zeigen sollen.Die vorherigen Antworten waren für .NET 1.1 korrekt (siehe Datum des verlinkten Beitrags: 2003). Ab .NET 2.0 und höher gibt es im Wesentlichen keinen Unterschied. Die JIT verweist ohnehin auf dasselbe Objekt auf dem Heap.
Gemäß der C # -Spezifikation, Abschnitt 2.4.4.5: http://msdn.microsoft.com/en-us/library/aa691090(VS.71).aspx
Jemand erwähnt dies sogar in den Kommentaren von Brad Abrams Beitrag
Zusammenfassend ist das praktische Ergebnis von "" vs. String.Empty gleich Null. Die JIT wird es am Ende herausfinden.
Ich persönlich habe festgestellt, dass die JIT viel schlauer ist als ich, und deshalb versuche ich, mit solchen Micro-Compiler-Optimierungen nicht zu schlau zu werden. Die JIT wird sich für () -Schleifen entfalten, redundanten Code, Inline-Methoden usw. besser und zu angemesseneren Zeiten entfernen, als ich oder der C # -Compiler jemals zuvor erwartet hätten. Lass die JIT ihren Job machen :)
quelle
String.Empty
ist ein Nur - Lese - während - Feld""
ist ein const . Dies bedeutet, dass SieString.Empty
eine switch-Anweisung nicht verwenden können , da sie keine Konstante ist.quelle
default
Schlüsselworts können wir die Lesbarkeit fördern, versehentliche Änderungen verhindern und eine Konstante für die Kompilierungszeit haben. Um ehrlich zu sein, denke ich immer noch, dass String.Empty besser lesbar als Standard ist, aber langsamer zu tippenEin weiterer Unterschied besteht darin, dass String.Empty einen größeren CIL-Code generiert. Während der Code für die Referenzierung von "" und String.Empty gleich lang ist, optimiert der Compiler die String-Verkettung (siehe Eric Lipperts Blog-Beitrag ) nicht für String.Empty-Argumente. Die folgenden äquivalenten Funktionen
Generieren Sie diese IL
quelle
"bar " + (ok ? "" : "error")
Die obigen Antworten sind technisch korrekt, aber was Sie wirklich verwenden möchten, um die beste Lesbarkeit des Codes und die geringste Wahrscheinlichkeit einer Ausnahme zu erzielen, ist String.IsNullOrEmpty (s)
quelle
--foo=$BAR
möchten Sie wahrscheinlich den Unterschied zwischen dem Vergessen, eine env var festzulegen, und dem Nichtübergeben des Flags erkennen.string.IsNullOrEmpty
ist oft ein Code-Geruch, dass Sie Ihre Eingaben nicht richtig validiert haben oder seltsame Dinge tun. Sie sollten im Allgemeinen keine leeren Zeichenfolgen akzeptieren, wenn Sie diese wirklich verwenden möchtennull
, oder so etwas wie einen Vielleicht / Option-Typ.Ich benutze
String.Empty
eher als""
aus einem einfachen, aber nicht offensichtlichen Grund:""
und""
sind NICHT gleich, der erste enthält tatsächlich 16 Zeichen mit einer Breite von Null. Natürlich wird kein kompetenter Entwickler Zeichen mit einer Breite von Null in seinen Code einfügen, aber wenn sie dort ankommen, kann dies ein Alptraum für die Wartung sein.Anmerkungen:
In diesem Beispiel habe ich U + FEFF verwendet .
Sie sind sich nicht sicher, ob SO diese Zeichen essen wird, aber versuchen Sie es selbst mit einem der vielen Zeichen mit der Breite Null
Ich bin nur dank https://codegolf.stackexchange.com/ darauf gestoßen.
quelle
Verwenden Sie
String.Empty
eher als""
.Referenz:
String.Empty
vs.""
quelle
String.Empty erstellt kein Objekt, während "" dies tut. Der hier erwähnte Unterschied ist jedoch trivial.
quelle
Alle Instanzen von "" sind das gleiche, internierte Zeichenfolgenliteral (oder sollten es sein). Sie werden also nicht jedes Mal, wenn Sie "" verwenden, ein neues Objekt auf den Heap werfen, sondern nur einen Verweis auf dasselbe internierte Objekt erstellen. Trotzdem bevorzuge ich string.Empty. Ich denke, es macht Code lesbarer.
quelle
Es ist einfach egal!
Einige frühere Diskussionen darüber:
http://www.codinghorror.com/blog/archives/000185.html
http://blogs.msdn.com/brada/archive/2003/04/22/49997.aspx
http://blogs.msdn.com/brada/archive/2003/04/27/50014.aspx
quelle
ldstr
verschiebt einen neuen Objektverweis auf ein in den Metadaten gespeichertes Zeichenfolgenliteral.ldsfld
schiebt den Wert eines statischen Feldes auf den AuswertungsstapelIch neige dazu,
String.Empty
anstatt zu verwenden,""
weil IMHO es klarer und weniger VB-ish ist.quelle
Hier sind einige Roslyn x64- Ergebnisse vom Januar 2019. Trotz der Konsensbemerkungen der anderen Antworten auf dieser Seite scheint es mir nicht, dass die aktuelle x64-JIT alle diese Fälle identisch behandelt, wenn alles gesagt und getan ist.
Beachten Sie jedoch insbesondere, dass nur eines dieser Beispiele tatsächlich aufgerufen wird
String.Concat
, und ich vermute, dass dies aus Gründen der unklaren Korrektheit geschieht (im Gegensatz zu einem Optimierungsversehen). Die anderen Unterschiede scheinen schwerer zu erklären.default (String) + {default (String), "", String.Empty}
"" + {default (String), "", String.Empty}
String.Empty + {default (String), "", String.Empty}
Testdetails
quelle
Aus Sicht von Entity Framework: EF-Versionen 6.1.3 scheinen String.Empty und "" bei der Validierung unterschiedlich zu behandeln.
string.Empty wird zu Validierungszwecken als Nullwert behandelt und löst einen Validierungsfehler aus, wenn er in einem erforderlichen (zugewiesenen) Feld verwendet wird. Dabei wird "" die Validierung bestehen und den Fehler nicht auslösen.
Dieses Problem kann in EF 7+ behoben werden. Referenz: - https://github.com/aspnet/EntityFramework/issues/2610 ).
Bearbeiten: [Erforderlich (AllowEmptyStrings = true)] behebt dieses Problem und ermöglicht die Validierung von string.Empty.
quelle
Da String.Empty keine Konstante zur Kompilierungszeit ist, können Sie sie nicht als Standardwert in der Funktionsdefinition verwenden.
quelle
public void test(int i=0, string s=string.Empty) {}
wird nicht kompiliert und sagt "Der Standardparameterwert für 's' muss eine Konstante für die Kompilierungszeit sein. Die Antwort von OP funktioniert.Wenn Sie Code visuell durchsuchen, wird "" so eingefärbt angezeigt, wie Zeichenfolgen eingefärbt sind. string.Empty sieht aus wie ein normaler Zugriff auf Klassenmitglieder. Während eines kurzen Blicks ist es einfacher, die Bedeutung zu erkennen oder zu verstehen.
Finde die Zeichenfolgen (die Stapelüberlauffärbung hilft nicht gerade, aber in VS ist dies offensichtlicher):
quelle
\u00ad
.Alle hier gaben eine gute theoretische Erklärung. Ich hatte einen ähnlichen Zweifel. Also habe ich eine grundlegende Codierung versucht. Und ich habe einen Unterschied gefunden. Hier ist der Unterschied.
Es scheint also, dass "Null" absolut nichtig bedeutet und "String.Empty" bedeutet, dass es einen Wert enthält, aber leer ist.
quelle
""
Versus handeltstring.Empty
. Nur beim Versuch festzustellen, ob die Zeichenfolge leer ist,null
wurde erwähnt.