2010-03-10 17 views
128

Etwas, das ich mehr und mehr mache, überprüft eine Zeichenfolge für leer (wie in "" oder null) und einen bedingten Operator.?? Koaleszieren für leere Zeichenfolge?

Ein aktuelles Beispiel:

s.SiteNumber.IsNullOrEmpty() ? "No Number" : s.SiteNumber; 

Dies ist nur eine Erweiterung Methode, es ist äquivalent zu:

string.IsNullOrEmpty(s.SiteNumber) ? "No Number" : s.SiteNumber; 

Da es leer und nicht null, ?? den Trick nicht. Eine string.IsNullOrEmpty() Version von ?? wäre die perfekte Lösung. Ich denke, dass es einen saubereren Weg geben muss (hoffe ich!), Aber ich war nicht in der Lage, es zu finden.

Kennt jemand eine bessere Möglichkeit, dies zu tun, auch wenn es nur in .Net 4.0 ist?

+8

Um Sie ein wenig zu quälen, können Sie einfach benutzerdefinierte, ad-hoc binäre (und unäre, für diese Angelegenheit) Operatoren in F # definieren.Hier 'let (|?) X y = if String.IsNullOrEmpty (x) dann y else x' und benutze es wie 's.SiteNumber |? "Keine Nummer" '. –

+0

Ich hoffe, dass Sie den Schnitt nicht stören. – gdoron

Antwort

61

Es gibt keine integrierte Möglichkeit, dies zu tun. Sie können Ihre Erweiterungsmethode jedoch dazu veranlassen, eine Zeichenfolge oder Null zurückzugeben, wodurch der Koaleszenzoperator arbeiten könnte. Das wäre jedoch merkwürdig, und ich persönlich bevorzuge Ihren derzeitigen Ansatz.

Da Sie bereits eine Erweiterungsmethode verwenden, warum macht man nicht nur, die den Wert oder einen Standardzurückgibt:

string result = s.SiteNumber.ConvertNullOrEmptyTo("No Number"); 
+6

Ich denke, Sie haben Recht, und dies ist die sauberste Lösung, die derzeit verfügbar ist, die immer noch lesbar ist. Ich würde etwas wie einen '???' Operator in C# 5 obwohl, wer weiß. –

+2

und was wäre das ??? Betreiber tun? nimmst du zusätzlich zu Nullen Standardwerte? klingt im besten Fall extrem kompliziert – bevacqua

+1

Mit Lambda-Ausdrücken vielleicht? Zum Beispiel: angenommen, "Artikel" ist Nullable, dann ... 'Artikel ?? x => x.ToString(): null; ' –

100

C# schon kann uns Ersatzwerte für null mit ??. Also alles, was wir brauchen, ist eine Erweiterung, die eine leere Zeichenfolge null umwandelt, und dann verwenden wir es so:

s.SiteNumber.NullIfEmpty() ?? "No Number"; 
3

wie wärs mit einem String-Extension-Methode ValueOrDefault()

public static string ValueOrDefault(this string s, string sDefault) 
{ 
    if (string.IsNullOrEmpty(s)) 
     return sDefault; 
    return s; 
} 

oder null zurück, wenn Zeichenkette ist leer:

public static string Value(this string s) 
{ 
    if (string.IsNullOrEmpty(s)) 
     return null; 
    return s; 
} 

Haben diese Lösungen nicht versucht.

+2

Ich mag Option # 1 dort, obwohl ich es etwas semantischer nennen würde wie Or(), also ich könnte schreiben "string s = s.SiteNumber.Or (" Default ");" – jvenema

+2

Das Aufrufen von '... OrDefault()' wäre verwirrend, wenn es sich nicht wie der Rest der '... OrDefault()' Methoden des Frameworks verhält. Ob Sie es mögen oder nicht, MS hat dieser Benennung eine spezifische Bedeutung gegeben und das Abweichen von diesem Verhalten in benutzerdefinierten Methoden führt zu unnötigen Verwirrungen für Nutzer Ihrer API. – mattmc3

28

Ich weiß, dass dies eine alte Frage - aber ich war auf der Suche nach einer Antwort und keiner der mein Bedürfnis oben passen als auch, was ich am Ende mit:

private static string Coalesce(params string[] strings) 
{ 
    return strings.FirstOrDefault(s => !string.IsNullOrEmpty(s)); 
} 

Verbrauch:

string result = Coalesce(s.SiteNumber, s.AltSiteNumber, "No Number"); 

EDIT: Eine noch kompaktere Möglichkeit, diese Funktion des Schreibens wäre:

static string Coalesce(params string[] strings) => strings.FirstOrDefault(s => !string.IsNullOrEmpty(s)); 
+1

Ich mag, aber musste einen Compilerfehler beheben und machte es ein bisschen kompakter. – gregmac

+0

Warum nennst du dieses Coalesce, wenn es die Werte nicht zusammenbringt, sondern nur dasjenige auswählt, das nicht leer ist? Es ist ein verwirrender Name, Mann. – Jimmyt1988

+0

Da Coalesce der Begriff ist, der von vielen Datenbanken verwendet wird, um dieselbe Operation auszuführen (ersten Nicht-Null-Wert finden). Strings zusammenfügen ist Verkettung. –

13

Ich habe ein paar von Utility-Erweiterungen, die ich verwenden möchte:

public static string OrDefault(this string str, string @default = default(string)) 
{ 
    return string.IsNullOrEmpty(str) ? @default : str; 
} 

public static object OrDefault(this string str, object @default) 
{ 
    return string.IsNullOrEmpty(str) ? @default : str; 
} 

Edit: von SFSR ‚s Antwort inspiriert, werde ich von jetzt an diese Variante zu meinem Werkzeugkasten das Hinzufügen:

public static string Coalesce(this string str, params string[] strings) 
{ 
    return (new[] {str}) 
     .Concat(strings) 
     .FirstOrDefault(s => !string.IsNullOrEmpty(s)); 
} 
+0

Ich verwende definitiv den Begriff "Coalesce", da er der Absicht des Nullkoaleszenzoperators (??) näher kommt, obwohl ich ihn in "CoalesceTo" geändert habe. – llaughlin

+0

Was bewirkt das Präfix '@' auf dem Parameter '@ default'? Das habe ich noch nie zuvor gesehen. –

+1

@druciferre - Damit können Sie 'default' nur als Variablennamen verwenden, obwohl es in C# ein reserviertes Schlüsselwort ist. –

6

eine etwas schnellere Erweiterungsmethode als früher vielleicht vorgeschlagen:

public static string Fallback(this string @this, string @default = "") 
{ 
    return (@this == null || @this.Trim().Length == 0) ? @default : @this; 
} 
+11

Warum nicht [IsNullOrWhitespace] (http://msdn.microsoft.com/en-us/library/system.string.isnullorwhitespace.aspx) verwenden, anstatt es zu trimmen und zu verlängern. – weston

+1

'code' öffentliche statische Zeichenfolge Coalesce (diese Zeichenfolge @this, string @default =" ") { Rückgabe (@this == null || String.IsNullOrWhiteSpace (@this))? @default: @this; } –

2

ich verwende einen String Coalesce ext ension Methode von meinen eigenen. Da die hier LINQ verwenden und absolutelly Ressourcen für zeitintensive Operationen verschwenden (ich verwende es in engen Schleifen), werde ich teilen Mine:

public static class StringCoalesceExtension 
{ 
    public static string Coalesce(this string s1, string s2) 
    { 
     return string.IsNullOrWhiteSpace(s1) ? s2 : s1; 
    } 
} 

Ich denke, es ist ganz einfach, und Sie don‘ t müssen sich sogar mit Null-String-Werten befassen. Verwenden Sie es wie folgt:

string s1 = null; 
string s2 = ""; 
string s3 = "loudenvier"; 
string s = s1.Coalesce(s2.Coalesce(s3)); 
Assert.AreEqual("loudenvier", s); 

Ich benutze es sehr. Eine dieser "Dienstprogramm" -Funktionen können Sie nicht leben ohne nach der ersten Verwendung :-)

0

Ich mag die Kürze der folgenden Erweiterungsmethode QQQ für diese, obwohl natürlich ein Betreiber wie? wäre besser. Aber wir können dies tun, indem wir nicht nur zwei, sondern drei String-Optionswerte vergleichen, denen man immer wieder begegnen muss (siehe zweite Funktion unten).

#region QQ 

[DebuggerStepThrough] 
public static string QQQ(this string str, string value2) 
{ 
    return (str != null && str.Length > 0) 
     ? str 
     : value2; 
} 

[DebuggerStepThrough] 
public static string QQQ(this string str, string value2, string value3) 
{ 
    return (str != null && str.Length > 0) 
     ? str 
     : (value2 != null && value2.Length > 0) 
      ? value2 
      : value3; 
} 


// Following is only two QQ, just checks null, but allows more than 1 string unlike ?? can do: 

[DebuggerStepThrough] 
public static string QQ(this string str, string value2, string value3) 
{ 
    return (str != null) 
     ? str 
     : (value2 != null) 
      ? value2 
      : value3; 
} 

#endregion 
2

Einer der Vorteile des Null-Koaleszenz-Operators ist, dass er kurzschließt. Wenn der erste Teil nicht null ist, wird der zweite Teil nicht ausgewertet. Dies kann nützlich sein, wenn der Fallback eine teure Operation erfordert.

Ich landete mit:

public static string Coalesce(this string s, Func<string> func) 
{ 
    return String.IsNullOrEmpty(s) ? func() : s; 
} 

Verbrauch:

string navigationTitle = model?.NavigationTitle. 
    Coalesce(() => RemoteTitleLookup(model?.ID)). // Expensive! 
    Coalesce(() => model?.DisplayName); 
0

ich einfach eine NullIfEmpty Extension-Methode verwenden, die immer null zurück, wenn der String leer ist erlaubt ?? (Null Koaleszierender Operator) wird normal verwendet.

public static string NullIfEmpty(this string s) 
{ 
    return s.IsNullOrEmpty() ? null : s; 
} 

Dies erlaubt dann ?? als normal zu verwenden und die Verkettung einfach zu lesen.

string string1 = string2.NullIfEmpty() ?? string3.NullIfEmpty() ?? string4; 
Verwandte Themen