c# value ?? Coalesce por corda vazia?




test if is null c# (8)

C # já nos permite substituir valores por null com ?? . Então, tudo que precisamos é de uma extensão que converta uma string vazia para null , e então nós a usamos assim:

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

Algo que eu me vejo fazendo mais e mais está verificando uma string para vazio (como em "" ou null) e um operador condicional.

Um exemplo atual:

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

Este é apenas um método de extensão, é equivalente a:

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

Já que está vazio e não é nulo ?? não vai fazer o truque. Uma versão string.IsNullOrEmpty() ?? seria a solução perfeita. Estou pensando que tem que haver uma maneira mais limpa de fazer isso (espero!), Mas não consegui encontrá-lo.

Alguém sabe de uma maneira melhor de fazer isso, mesmo que seja apenas no .net 4.0?


Eu sei que esta é uma pergunta antiga - mas eu estava procurando por uma resposta e nenhuma das opções acima se encaixam na minha necessidade, bem como no que acabei usando:

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

Uso:

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

EDIT: Uma maneira ainda mais compacta de escrever essa função seria:

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

Eu gosto da brevidade do seguinte método de extensão QQQ para isso, embora, claro, um operador gosta? seria melhor. Mas podemos aumentar isso permitindo que não apenas dois, mas três valores de opção de string sejam comparados, o que é necessário para tratar de vez em quando (veja a segunda função abaixo).

#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

que tal um método de extensão de string ValueOrDefault ()

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

ou retornará null se string estiver vazia:

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

Não tente estas soluções embora.


Eu tenho algumas extensões de utilitário que gosto de usar:

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;
}

Editar: Inspirado pela resposta do sfsr , vou adicionar esta variante à minha caixa de ferramentas a partir de agora:

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

Uma das vantagens do operador de coalescência nula é que ele causa curto-circuito. Quando a primeira parte não é nula, a segunda parte não é avaliada. Isso pode ser útil quando o fallback requer uma operação cara.

Acabei com:

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

Uso:

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

Não há uma maneira interna de fazer isso. Você poderia fazer seu método de extensão retornar uma string ou null, no entanto, o que permitiria que o operador de coalescência funcionasse. Isso seria estranho, no entanto, e eu pessoalmente prefiro sua abordagem atual.

Como você já está usando um método de extensão, por que não apenas criar um que retorne o valor ou um padrão:

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

Eu estou usando uma string Coalesce método de extensão do meu próprio. Já que aqueles aqui estão usando o LINQ, e gastando recursos para operações intensivas de tempo (estou usando em loops apertados), compartilharei o meu:

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

Eu acho que é bem simples, e você nem precisa se preocupar com valores de string nulos. Use assim:

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

Eu uso isto muito. Uma daquelas funções "utilidade" que você não pode viver sem depois de usá-lo :-)





null-coalescing-operator