2010-08-31 6 views
14

Dieser Code ist nicht gültig:C# 4.0 - Wie Griff Optional String-Parameter

private void Foo(string optionalString = string.Empty) 
{ 
    // do foo. 
} 

Aber dieser Code:

private void Foo(string optionalString = "") 
{ 
    // do foo. 
} 

Warum? Da string.Empty ein schreibgeschütztes Feld und keine Konstante ist und die Standardwerte für optionale Parameter eine Kompilierungszeitkonstante sein müssen.

Also, auf meine Frage ... (na ja, Sorge)

Das ist, was ich zu tun haben musste:

private const string emptyString = ""; 

private void Foo(string optionalString = emptyString) 
{ 
    // do foo. 
    if (!string.IsNullOrEmpty(optionalString)) 
     // etc 
} 

How do you Jungs behandeln optionale String-Parameter?

Warum können sie nicht String.Empty eine Kompilierzeitkonstante machen?

+2

warum nicht halten mit „?“ Das ist alles, was ich mache, aber das liegt auch daran, dass ich den Vorteil der Verwendung von String.Empty nicht verstehe. Muss eine Unicode-Sache sein, aber ich muss mich nie darum kümmern (zumindest noch nicht ... yikes) – Dave

+1

Ich bin verwirrt, warum du denkst, dass du das * brauchst *. Ich halte 'nullString' für einen verwirrenden Namen, weil ich auf den ersten Blick geneigt wäre zu denken, es sei 'null', nicht '' ''. Was Ihre letzte Frage betrifft, siehe [ Warum ist String.Empty keine Konstante? ] (http://stackoverflow.com/questions/507923/why-isnt-string-empty-a-constant). @Dave, hier gibt es keine Unicode-Sache. "" "ist in Ordnung; siehe auch [ In C#, sollte ich string.Empty oder String.Empty oder "" verwenden? ] (http://stackoverflow.com/questions/263191/in-c-should-i-use-string-empty-or-string-empty-or). –

+0

Bitte erwähnen Sie die Version. – PrateekSaluja

Antwort

10

Ummm ... was ist falsch mit String optionalParm = "" wieder? Warum ist das so schlimm? Denken Sie wirklich, dass Sie in diesem Fall eine symbolische Konstante für eine leere Zeichenfolge benötigen? Wie wäre es damit?

const int Zero = 0; 

void SomeMethod(int optional = Zero) { } 

Das scheint überhaupt albern zu sein?

+1

Einverstanden, ich nannte das schlecht. Ich habe mich so sehr daran gewöhnt, string.empty für die meisten String-Operationen zu verwenden. Als ich anfing, optionale Parameter zu verwenden, gefiel mir nicht, dass ich zurück zu "" gehen musste. Schätze, ich bleibe bei "". – RPM1984

+0

Fabelhafter Modus: Wenn Sie wollen, dass die Leute Ihren Code als "Null" und nicht als "Null" lesen, dann ist es vielleicht OK – Davos

+3

Warum solch eine unhöfliche Antwort? Das OP hatte eine berechtigte Frage. – webworm

2

Der beste Weg, sie zu behandeln ist mit:

private void Foo(string optionalString = "") 
{ 
    // do foo. 
} 

So können Sie nicht String.Empty verwenden. Jeder erkennt "", aber wenn ich optionalString = nullString finden würde, wäre ich mir nicht sicher, was ich denken soll. Wenn nichts anderes, benennen Sie das Ding emptyString - es ist nicht null!

+1

Einverstanden, ich nannte das schlecht. Ich habe mich so sehr daran gewöhnt, string.empty für die meisten String-Operationen zu verwenden. Als ich anfing, optionale Parameter zu verwenden, gefiel mir nicht, dass ich zurück zu "" gehen musste. Schätze, ich bleibe bei "". – RPM1984

0

Ich beantworte diese Frage.

Why can they not make String.Empty a compile-time constant?

Hier ist der disassemble Code über Reflektor aus String.cs in mscorlib.dll

public static readonly Empty; 
static String() 
{ 
    Empty = ""; 
    WhitespaceChars = new char[] { 
     '\t', '\n', '\v', '\f', '\r', ' ', '\x0085', '\x00a0', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 
     ' ', ' ', ' ', ' ', '​', '\u2028', '\u2029', ' ', '' 
    }; 
} 

So in Windows-Plattform, ist string.Empty genau "". Aber wissen Sie, Martian haben eine andere Definition für Empty und WhitespaceChars in ihrem Betriebssystem.

4

Wenn Sie "" Wert nicht mögen, können Sie Standard (Zeichenfolge) verwenden.
Ich spielte damit und es ist erlaubt.

private static void foo(string param = default(string)) { 
    if (!string.IsNullOrEmpty(param)) // or param != default(string) 
     Console.WriteLine(param); 
} 
+6

Der Standardwert (Zeichenfolge) ist null, keine leere Zeichenfolge. – allonhadaya

+0

@allonhadaya, die Angabe eines Nicht-'null'-Standardwerts verhindert nicht, dass explizit 'null' :-p übergeben wird. – binki

+0

@Binki, ich bin mir nicht sicher, ob ich Ihren Standpunkt verstehe. Was meinen Sie? – allonhadaya

0

Wenn Sie bereit sind zu spielen zu verlieren und behandeln null, „“ und Leerzeichen gleich sein, dann können Sie auf null Standard. Dies ist sehr praktisch, wenn Benutzername und Kennwort optionale Felder sind, da eine vertrauenswürdige Verbindung zu einer Datenbank möglich ist. Sie könnten diese Logik ändern, um Strings auf null zurückzusetzen und somit den Assert und den if zu modifizieren. Der wichtige Teil ist eine konsistente Konvention.

private void RunSql(string serverName, string databaseName, string userName = null, string password = null) 
{ 
    userName = Strip(userName); 
    password = Strip(password); 

    // The `MsTest` assert - works in both `Debug` and `Release` modes. 
    Assert.AreEqual<bool>(
     userName == String.Empty, 
     password == String.Empty, 
     "User name and password should be either both empty or both non-empty!"); 
    Assert.IsFalse(String.IsNullOrWhiteSpace(serverName)); 
    Assert.IsFalse(String.IsNullOrWhiteSpace(databaseName)); 

    var cmdBuilder = new StringBuilder(); 
    cmdBuilder.AppendFormat("sqlcmd -E -S {0} -d {1} ", serverName, databaseName); 
    if (userName.Length > 0) 
    { 
     cmdBuilder.AppendFormat("-U {0} -P {1} ", userName, password); 
    } 

    // Complete the command string. 
    // Run the executable. 
} 

// Cannot think of a good name. Emptify? MakeNullIfEmpty? 
private string Strip(string source) 
{ 
    if (String.IsNullOrWhiteSpace(source)) 
    { 
     return String.Empty; 
    } 

    return source; 
} 
1

Code Analysis warning 1026 besagt, keine optionalen Parameter zu verwenden.Es ist besser, Stil Überlastung Methoden zu verwenden, wie folgt aus:

private void Foo() 
{ 
    Foo(string.Empty); 
} 
private void Foo(string optionalString) 
{ 
    // do foo. 
    if (!string.IsNullOrEmpty(optionalString)) 
     // etc 
}