web-dev-qa-db-fra.com

?? Coalesce pour chaîne vide?

Je cherche de plus en plus à vérifier qu'une chaîne est vide (comme dans "" Ou null) et un opérateur conditionnel.

Un exemple actuel:

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

Ceci est juste une méthode d'extension, cela équivaut à:

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

Comme il est vide et non nul, ?? Ne fera pas l'affaire. Une version string.IsNullOrEmpty() de ?? Serait la solution parfaite. Je pense qu'il doit y avoir une façon plus propre de le faire (j'espère!), Mais j'ai été incapable de le trouver.

Est-ce que quelqu'un connaît une meilleure façon de faire cela, même si c'est seulement en .Net 4.0?

151
Nick Craver

Il n'y a pas de manière intégrée de faire cela. Vous pouvez toutefois demander à votre méthode d’extension de renvoyer une chaîne ou une valeur null, ce qui permettrait à l’opérateur de coalescence de fonctionner. Ce serait étrange, cependant, et je préfère personnellement votre approche actuelle.

Puisque vous utilisez déjà une méthode d’extension, pourquoi ne pas en créer une qui retourne la valeur ou une valeur par défaut:

string result = s.SiteNumber.ConvertNullOrEmptyTo("No Number");
69
Reed Copsey

C # nous permet déjà de substituer des valeurs pour null par ??. Donc tout ce dont nous avons besoin est une extension qui convertit une chaîne vide en null, et nous l'utilisons comme ceci:

s.SiteNumber.NullIfEmpty() ?? "No Number";
117
RedFilter

Je sais que c'est une vieille question - mais je cherchais une réponse et aucune des réponses ci-dessus ne correspondait à mes besoins et à ce que j'ai fini par utiliser:

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

Usage:

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

EDIT: Une manière encore plus compacte d’écrire cette fonction serait:

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

J'ai quelques extensions utilitaires que j'aime utiliser:

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: Inspiré par la réponse de sfsr, je vais ajouter cette variante à ma boîte à outils à partir de maintenant:

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

Une méthode d'extension légèrement plus rapide que celle proposée précédemment peut-être:

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

L'un des avantages de l'opérateur à coalescence nulle est qu'il court-circuite. Lorsque la première partie n'est pas nulle, la deuxième partie n'est pas évaluée. Cela peut être utile lorsque le repli nécessite une opération coûteuse.

J'ai fini avec:

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

Usage:

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

J'utilise simplement une méthode d'extension NullIfEmpty qui renvoie toujours la valeur null si la chaîne est vide, permettant ainsi ?? (Opérateur de coalescence nul) à utiliser normalement.

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

Cela permet alors ?? à utiliser normalement et facilite l'enchaînement des chaînes.

string string1 = string2.NullIfEmpty() ?? string3.NullIfEmpty() ?? string4;
4
jjr2000

que diriez-vous d'une méthode d'extension de chaîne ValueOrDefault ()

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

ou renvoie null si la chaîne est vide:

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

Je n'ai pas essayé ces solutions cependant.

3
devio

J'utilise ma propre méthode d'extension de chaîne Coalesce. Étant donné que ceux-ci utilisent LINQ et gaspillent des ressources pour des opérations gourmandes en temps (je l'utilise en boucle serrée), je vais partager le mien:

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

Je pense que c'est assez simple, et vous n'avez même pas besoin de vous embêter avec des valeurs de chaîne nulles. Utilisez-le comme ceci:

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

Je l'utilise beaucoup. Une de ces fonctions "utilitaires" dont vous ne pouvez plus vous passer après l'avoir utilisé :-)

3
Loudenvier

J'aime la brièveté de la méthode d'extension suivante QQQ pour cela, bien sûr, un opérateur aime? serait mieux. Mais nous pouvons le faire en permettant de comparer non pas deux, mais trois valeurs d’option de chaîne, ce qui impose de traiter de temps en temps (voir la deuxième fonction ci-dessous).

#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
0
Nicholas Petersen