2010-04-23 6 views
76

Ich lese Effektive C# von Bill Wagner. In Punkt 14 - Minimieren Doppelte Initialisierung Logic, zeigt er das folgende Beispiel die neuen optionalen Parameter mithilfe der Funktion in einem Konstruktor:Kann String.Empty nicht als Standardwert für einen optionalen Parameter verwenden

public MyClass(int initialCount = 0, string name = "")

Beachten Sie, dass er "" statt string.Empty verwendet.
Er kommentiert:

Sie werden bemerken, [in einem Beispiel oben], dass der zweite Konstruktor angegeben „“ für den Standardwert auf den Namen Parameter, anstatt die üblichen string.Empty. Das liegt daran, dass string.Empty keine Kompilierzeitkonstante ist. Es ist eine statische Eigenschaft, die in der String-Klasse definiert ist. Da es sich nicht um eine Kompilierkonstante handelt, können Sie sie nicht als Standardwert für einen Parameter verwenden.

Wenn wir die Statik nicht in allen Situationen verwenden können, hat das dann nicht den Zweck? Ich dachte, wir würden es benutzen, um sicher zu sein, dass wir eine systemunabhängige Methode haben, auf die leere Zeichenfolge zu verweisen. Ist mein Verständnis falsch? Vielen Dank.

UPDATE
Nur ein Follow-up-Kommentar. Nach MSDN:

Jeder optionale Parameter hat einen Standardwert als Teil seiner Definition. Wenn für diesen Parameter kein Argument gesendet wird, wird der Standardwert verwendet. Standardwerte müssen Konstanten sein.

Dann werden wir System.Environment.NewLine nicht in der Lage sein, entweder zu verwenden oder neu instanziiert Objekte als Standardwert verwenden. Ich habe VS2010 noch nicht benutzt, und das ist enttäuschend!

+2

Mir sind keine Unterschiede zwischen der Darstellung leerer Strings auf verschiedenen Plattformen bekannt. Es ist nicht wie Newline. –

+0

Richtig, ich dachte das, also ist es nur, dass es im Code schöner aussieht? – Mikeyg36

+1

Die CLR und nicht das 'System' ist der ausschlaggebende Faktor, ob "" eine leere Zeichenfolge ist oder nicht. Ich denke also, Sie können sicher davon ausgehen, dass das "" eine systemunabhängige Methode ist, um auf eine Zeichenfolge bei einer konformen CLR-Implementierung zu verweisen. –

Antwort

52

Ab dem C# 2.0-Compiler, gibt es sehr wenig Punkt String.Empty sowieso, und in der Tat in vielen Fällen ist es ein pessimisation, da der Compiler einige Verweise auf "" inline kann, aber das gleiche mit String.Empty nicht tun.

In C# 1.1 war es nützlich zu vermeiden, viele unabhängige Objekte zu erstellen, die alle die leere Zeichenfolge enthalten, aber diese Tage sind weg. "" funktioniert gut.

+7

Selbst in .NET 1.1 würde es nicht "viele" unabhängige Objekte erstellen. Ich kann mich nicht erinnern, die Details der Unterschiede zwischen 1.1 und 2.0 in dieser Hinsicht, aber es ist nicht wie String-Literal-Interning wurde nur in 2.0 eingeführt. –

+0

Danke für die Klarstellung. Ich habe mich umgesehen und ich habe keine gute Zusammenfassung der Änderungen in C# 2.0 gefunden, obwohl ich sicher bin, dass ich zuvor eine gelesen habe. Ich habe eine StackOverflow-Antwort von 2008 mit einigen Links zu mehr technischen Informationen gefunden. http://stackoverflow.com/questions/151472/what-is-the-difference-between-string-emppty-and –

+1

Ich werde dies ein Nicken geben, obwohl ich nicht mag sagen, dass es wenig Sinn zu string.Empty als ich benutze es ziemlich stark. Ich finde es sieht einfach sauberer aus, obwohl das meine persönliche Meinung ist. Es gibt viele Orte string.Empty kann nicht verwendet werden, und ich habe kein Problem mit "" in diesen Fällen – xximjasonxx

7

Ich benutze nie string.Empty, ich kann nicht den Sinn davon sehen. Vielleicht ist es für Leute, die wirklich neu in der Programmierung sind, einfacher, aber ich bezweifle, dass es sogar dafür nützlich ist.

+2

Vielleicht verhindert es verwirrend "" " und '' '', aber ich kann nicht sagen, dass '' '' all das ist üblich. – Greg

+8

Ich würde vorschlagen, dass jeder, der den Unterschied zwischen diesen beiden nicht unterscheiden kann, entweder eine bessere Brille braucht oder um die Auflösung ihres Bildschirms zu verringern. Ich habe schlechte Sehkraft und kann mich nicht erinnern, jemals diesen Fehler gemacht zu haben (und ich muss mit einer Menge Code arbeiten, der beides enthält). –

+1

string.Empty ist nützlich, um die genaue Absicht des Programmierers herauszufinden. "" sagt nichts über die Absicht, was ist, wenn die Programmiererin beabsichtigt, die Variable wie dieses "lol" zu initialisieren, aber vergessen hat ... in diesem Fall gibt es endlose Möglichkeiten und Zeichenketten, Leere ist praktisch und macht einen besseren Job – usefulBee

4

Ich denke, die Idee hinter string.Empty ist es verbessert die Lesbarkeit. Es ist nicht wie Newline, wo es einen Unterschied gibt, wie es auf verschiedenen Plattformen dargestellt wird. Es ist schade, dass es nicht in einem Standardparameter verwendet werden kann. Es wird jedoch keine Probleme verursachen, wenn Sie zwischen Windows und etwas wie Mono unter Linux portieren.

+5

I Ich denke, Sie haben wahrscheinlich Recht, dass einige Leute 'String.Empty' für besser lesbar halten. . . persönlich denke ich, das ist ein bisschen nussig. "" "ist wahrscheinlich die häufigste Zeichenfolge, die es gibt, und jeder hat es eine Milliarde Mal gesehen, also wie ist es nicht lesbar? 'String.Empty' ist ungefähr so ​​nützlich, als ob es ein' Int32.Zero' gäbe. –

50

Es gibt nichts, Sie zu stoppen von Ihrer eigenen Konstante für die leere Zeichenkette definieren, wenn Sie es wirklich als optionale Parameterwert verwenden möchten:

const string String_Empty = ""; 

public static void PrintString(string s = String_Empty) 
{ 
    Console.WriteLine(s); 
} 

[Als beiseite, ein Grund String.Empty über "" zu bevorzugen Im Allgemeinen wurde dies in den anderen Antworten nicht erwähnt. Es gibt verschiedene Unicode-Zeichen (Null-Breiten-Verbinder usw.), die für das bloße Auge effektiv unsichtbar sind. So etwas, das wie "" aussieht, ist nicht unbedingt die leere Zeichenfolge, während mit Sie genau wissen, was Sie verwenden. Ich weiß, dass dies keine häufige Fehlerquelle ist, aber es ist möglich.]

+12

+1. Sie machen "String.Empty" so, als ob es einen Zweck hat! – TarkaDaal

+2

Es gibt auch unsichtbare Bezeichnerzeichen, also etwas, das wie String_Empty aussieht, ist nicht unbedingt. Der Unicode-Standard enthält ein weitgehend ignoriertes Kapitel zu Sicherheitsaspekten. –

3

Wie es aussieht, sieht es so aus, als ob die gleichen Bedingungen an Attributkonstruktoren übergeben werden - sie müssen konstant sein. Da string.empty wie folgt definiert ist:

eher als eine tatsächliche Konstante, kann es nicht verwendet werden.

20

Von der ursprünglichen Frage:

Ich dachte, dass wir es sicher sein, verwenden würden, dass wir eine systemunabhängige mittels Bezugnahme auf die leere Zeichenkette haben.

Inwiefern kann die leere Zeichenfolge von System zu System variieren? Es ist immer eine Zeichenfolge ohne Zeichen! Ich wäre wirklich Angst, wenn ich jemals eine Implementierung gefunden, wo falsch zurückgegeben :) Dies ist nicht das gleiche wie etwas wie Environment.NewLine.

Von Gegenterroristen Bounty Beitrag:

Ich mag String.Empty kann als Standardparameter in der nächsten C# Release verwendet werden. : D

Nun, das wird sicherlich nicht passieren.

Während mir persönlich ein anderer Standardmechanismus gefallen wäre, ist die Art, wie optionale Parameter funktionieren, seit dem Start in .NET - und es bedeutet immer eine Konstante in die Metadaten einzubetten, damit der aufrufende Code das kopieren kann Konstante in die Aufrufseite, wenn kein entsprechendes Argument angegeben wird.

Mit string.Empty ist es wirklich sinnlos - mit "" wird tun, was Sie wollen; ist es , dass schmerzhaft ist, das Zeichenfolgenliteral zu verwenden? (Ich benutze die wörtlichen überall - ich string.Empty nie benutzen - aber das ist ein anderes Argument.)

Das ist, was ich überrascht über diese Frage - die Beschwerde dreht sich um etwas, das nicht tatsächlich ein echtes Problem verursachen. Es ist wichtiger in Fällen, in denen der Standardwert zur Ausführungszeit berechnet werden soll, da er sich tatsächlich ändern kann. Zum Beispiel könnte ich mir Fälle vorstellen, in denen Sie eine Methode mit einem DateTime Parameter aufrufen können und standardmäßig "die aktuelle Zeit" haben.Im Moment der einzige vage elegante Abhilfe, die ich für das wissen ist:

public void RecordTime(string message, DateTime? dateTime = null) 
{ 
    var realDateTime = dateTime ?? DateTime.UtcNow; 
} 

... aber das ist nicht immer angemessen.

Fazit:

  • Ich bezweifeln sehr, dass dies jemals Teil von C#
  • Für string.Empty es ist sinnlos sowieso
  • Für andere Werte sein, die wirklich nicht immer das gleiche haben Wert, es wirklich kann ein Schmerz sein
+0

Dies ist eigentlich eine gute Möglichkeit, das Problem zu beheben. Das gleiche Ding kann verwendet werden, um andere geräteabhängige Variablen wie '' Environment.Newline'' zu tragen/setzen. Das einzige, was in Ihrem Beispiel fehlt, wäre eine Überprüfung der Variablen auf Null und das Zurückwerfen einer Ausnahme an den Entwickler ihm, dass, obwohl es nullfähig ist, es nicht akzeptiert wird. '' if (dateTime == null) {Neue argumentException auslösen ("Der dateTime-Parameter muss gesetzt sein. NULL-Typ wird für geräteunabhängige Variablen verwendet.");} '' oder so ähnlich. Aber ich mag das wirklich! Irgendwelche anderen Vorbehalte, es auf Ihre Art zu tun? – MaxOvrdrv

+0

@MaxOvrdrv: Sie wollen nicht, dass es null ist, um ein Fehler zu sein - der ganze Punkt ist, dass, wenn es null ist, Sie einen Standard berechnen. Der Vorbehalt besteht darin, dass NULL nicht als gültiger Wert an sich übergeben werden darf. –

+0

Sie haben völlig Recht damit. Mein Fehler. - Und ja, das wäre die einzige wirkliche Einschränkung, nicht wahr ... das ist nicht so schlimm. Nochmal: Ich mag diese Lösung wirklich! :) Danke für das Posten! :) – MaxOvrdrv

2

Wenn Sie wirklich nicht wie st Ring Literale, können Sie verwenden:

public static string MyFunction(string myParam= default(string)) 
+2

default (string) würde null, nicht string.Empty zurückgeben. – lgaud

+0

http://msdn.microsoft.com/en-us/library/xwth0h0d.aspx Ah richtig. Ich habe vergessen String ist eigentlich eine Referenz und kein Wert. –

-1

Vielleicht ist die beste Lösung für dieses Problem ist eine Überlastung dieser Methode, auf diese Weise:

public static void PrintString() 
{ 
    PrintString(string.Empty); 
} 
+3

Wie das die obige Frage beantworten? –

+1

Wie hilft es bei Standardwerten für optionale Parameter? –

0

Ich benutze string.Empty rein aus Gründen der Lesbarkeit.

Wenn jemand anderes meinen Code später lesen/ändern muss, weiß er, dass ich nach etwas suchen oder etwas auf eine leere Zeichenfolge setzen wollte. Die Verwendung von nur "" kann manchmal Fehler und Verwirrung verursachen, weil ich vielleicht vergessen habe, die Zeichenfolge, die ich wollte, dort zu setzen.

Zum Beispiel:

if(someString == string.Empty) 
{ 

} 

vs

if(someString == "") 
{ 

} 

Die erste if Aussage scheint nur so viel bewusste und lesbar zu mir. Da dies jedoch nur eine Vorliebe ist, sehe ich wirklich nicht den Zug-Smash, "" anstelle von string.Empty zu verwenden.