"??" 运算符的作用是什么?

35

4
要了解 C# 中其他有趣的语法,请查看以下链接:https://dev59.com/b-o6XIcBkEYKwwoYTzRZ - tster
"null coalescing operator" 是一个让人很不舒服的名字。哈哈。而且“coalescing”的正确发音是什么? - carloswm85
12个回答

53

这是空值合并运算符,它在C# 2中被引入。

表达式a ?? b的结果是如果a不是null,则为a,否则为b。除非需要,否则不会评估b

两个好处:

  • The overall type of the expression is that of the second operand, which is important when you're using nullable value types:

    int? maybe = ...;
    int definitely = maybe ?? 10;
    

    (Note that you can't use a non-nullable value type as the first operand - it would be pointless.)

  • The associativity rules mean you can chain this really easily. For example:

    string address = shippingAddress ?? billingAddress ?? contactAddress;
    
这将使用运输、账单或联系地址中的第一个非空值。

3
+1 表示:“除非需要,否则不会评估第二个操作数”。这类情况很容易被忽略。 - Konamiman
1
这应该与https://dev59.com/QXRA5IYBdhLWcg3wyBH1合并,因为那是一个更完整的答案。 - Sam Saffron
它等同于a!= null?a:b - dharga
@dharga:除了只评估a一次之外,它什么都没有。 - Jon Skeet

35

它被称为“null合并运算符”,其工作原理大致如下:

不要这样做:

int? number = null;
int result = number == null ? 0 : number;

现在你可以这样做:

int result = number ?? 0;

实际上,x ?? y 调用的是 x.GetValueOrDefault(y) 方法(IL 代码:call instance !0 valuetype [mscorlib]System.Nullable1<int32>::GetValueOrDefault()`)。 - Aidiakapi

12

8

这是一个快捷方式:

Text = (category == null ? "Home" : category);

8

7

这是一个合并运算符,如果第一个值为空,它将返回另一个值。

string value1 = null;
string value2 = "other";

string value3 = value1 ?? value2; // assigns "other" to value 3

5

它会检查类别是否为空 - 当这种情况发生时,空值将被替换为“主页”。


4

我最喜欢使用空值合并运算符的方法之一是避免在代码中使用if语句(我认为if语句往往很丑陋,只会让事情变得混乱)。例如,考虑一个典型的场景,如果可用,则从缓存中加载某些内容,否则从数据库中加载并填充缓存。

private SomeData GetData() {
    var data = HttpRuntime.Cache.Get("key") as SomeData;

    if (data == null) {
        data = DAL.GetData(some parameters...);
        HttpRuntime.Cache.Add("key", data, ....);
    }

    return data;
}

对我来说,那是丑陋的代码。也许我有点追求完美,但为什么不重构成这样呢?
private SomeData GetDataAndCache() {
    var data = DAL.GetData(some parameters...);
    HttpRuntime.Cache.Add("key", data, ....);
    return data;
}

private SomeData GetData() {
    var data = HttpRuntime.Cache.Get("key") as SomeData;
    return data ?? GetDataAndCache();
}

在我看来,它更贴近SRP原则,也更加简洁易读。每个函数都只执行一个明确可识别的功能。


SRP:单一职责原则。 - Chris
我想知道编译器是否会将其与MSIL中的IF语句渲染不同。有人知道吗? - Jagd
1
我对此表示怀疑,但不会因为不知道而失眠。 - Darren Kopp
2
我不知道“if”语句为什么那么丑陋,但是“只赋值一次”的编程范式是一个很好的选择,当你可以在不破坏代码自然流程的情况下使用它。 - Roboprog
“if”语句是否难看这个问题肯定是主观的,而且我怀疑我的方法是否能提高性能。就像我之前所说,它只是让代码更加整洁和易于理解,这是我个人的看法。 - Chris

4
如果类别为空,文本将变为“主页”。

2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接