??合并空字符串?

时间:2010-03-10 20:01:10

标签: c# string coalesce null-coalescing-operator

我发现自己做的越来越多的事情是检查字符串为空(如""或null)和条件运算符。

目前的例子:

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

这只是一种扩展方法,它相当于:

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

由于它是空的而不是空的,??将无法解决问题。 string.IsNullOrEmpty()??将是完美的解决方案。我认为必须有一个更清洁的方式来做这件事(我希望!),但我一直在找不到它。

有没有人知道更好的方法,即使它只在.Net 4.0中?

10 个答案:

答案 0 :(得分:115)

C#已经允许我们用null替换??的值。所以我们需要的是一个将空字符串转换为null的扩展,然后我们像这样使用它:

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

答案 1 :(得分:68)

没有内置方法可以做到这一点。您可以使您的扩展方法返回一个字符串或null,但这将允许合并运算符工作。然而,这很奇怪,我个人更喜欢你现在的做法。

由于您已经在使用扩展方法,为什么不只是创建一个返回值或默认值:

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

答案 2 :(得分:34)

我知道这是一个老问题 - 但我一直在寻找答案,以上所有内容都不符合我的需要以及我最终使用的内容:

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

用法:

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

修改 编写此函数的更紧凑的方法是:

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

答案 3 :(得分:15)

我有几个我喜欢使用的实用程序扩展:

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

编辑:受 sfsr 的回答启发,我将从现在开始将此变体添加到我的工具箱中:

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

答案 4 :(得分:6)

比之前提出的稍微快一点的扩展方法:

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

答案 5 :(得分:5)

归零运算符的一个优点是它短路。当第一部分不为null时,不评估第二部分。当后备需要昂贵的操作时,这可能很有用。

我最终得到了:

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

用法:

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

答案 6 :(得分:3)

字符串扩展方法ValueOrDefault()

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

如果string为Empty,则返回null:

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

虽然没有尝试过这些解决方案。

答案 7 :(得分:2)

我正在使用我自己的字符串Coalesce扩展方法。由于这里的人正在使用LINQ,并且绝对浪费资源进行时间密集型操作(我在紧密循环中使用它),我将与我分享:

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

我认为这很简单,你甚至不需要打扰空字符串值。像这样使用它:

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

我经常使用它。其中一个“实用”功能,在你第一次使用它之后就不能没有了: - )

答案 8 :(得分:2)

我只是使用NullIfEmpty扩展方法,如果字符串为空,它将始终返回null允许? (Null Coalescing Operator)正常使用。

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

这允许??正常使用,使链接易于阅读。

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

答案 9 :(得分:0)

我喜欢以下扩展方法QQQ的简洁,虽然操作员当然喜欢?会更好。但是我们可以通过不仅仅允许两个而是三个字符串选项值进行比较,其中一个偶尔会遇到需要处理的问题(参见下面的第二个函数)。

#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