在 C#中,两个问号一起意味着什么?

遍历以下代码行:

FormsAuth = formsAuth ?? new FormsAuthenticationWrapper();

这两个问号是什么意思,是某种三元运算符吗?在 Google 中很难查找。

答案

它是空值合并运算符,与三元运算符(即时 if)非常相似。另请参阅?? 运营商 - MSDN

FormsAuth = formsAuth ?? new FormsAuthenticationWrapper();

扩展为:

FormsAuth = formsAuth != null ? formsAuth : new FormsAuthenticationWrapper();

进一步扩展为:

if(formsAuth != null)
    FormsAuth = formsAuth;
else
    FormsAuth = new FormsAuthenticationWrapper();

在英语中,这意味着 “如果左侧的内容不为 null,请使用该名称,否则请使用右侧的内容。”

请注意,您可以依次使用任何数量的这些。以下语句将第一个非空的Answer#分配给Answer (如果所有 Answers 为 null,则Answer为 null):

string Answer = Answer1 ?? Answer2 ?? Answer3 ?? Answer4;

同样值得一提的是,以上扩展在概念上是等效的,每个表达式的结果仅计算一次。例如,如果表达式是具有副作用的方法调用,则这一点很重要。 (请指出 @Joey,以指出这一点。)

只是因为没有人说过神奇的话:它是null 合并运算符 。它在C#3.0 语言规范的 7.12 节中定义。

它非常方便,特别是因为它在表达式中多次使用时的工作方式。形式的表达式:

a ?? b ?? c ?? d

会给表达式的结果a ,如果它是不为空,否则尽量b ,否则尽量c ,否则试试d 。它在每个点都短路。

同样,如果d的类型是不可为 null 的,则整个表达式的类型也将不可为 null。

它是空合并运算符。

http://msdn.microsoft.com/en-us/library/ms173224.aspx

是的,除非您知道它的名字,否则几乎不可能进行搜索! :-)

编辑:这是另一个问题的一个很酷的功能。您可以将它们链接起来。

C#的隐藏功能?

谢谢大家,这是我在 MSDN 站点上找到的最简洁的解释:

// y = x, unless x is null, in which case y = -1.
int y = x ?? -1;

??当该值为 null 时,是否可以为可为 null 的类型提供值。因此,如果 formsAuth 为 null,它将返回新的 FormsAuthenticationWrapper()。

在此处输入图片说明

两个问号(??)表示其为合并运算符。

合并运算符从链返回第一个 NON-NULL 值。您可以观看此 youtube 视频 ,它实际上演示了整个过程。

但是,让我在视频中添加更多内容。

如果您看到合并的英文含义,那就说 “巩固”。例如,下面是一个简单的合并代码,它链接了四个字符串。

因此,如果str1null ,它将尝试str2 ;如果str2null ,则将尝试str3 ,依此类推,直到找到具有非 null 值的字符串。

string final = str1 ?? str2 ?? str3 ?? str4;

用简单的话说,合并运算符从链中返回第一个 NON-NULL 值。

这是三元运算符的简写。

FormsAuth = (formsAuth != null) ? formsAuth : new FormsAuthenticationWrapper();

或对于那些不做三元的人:

if (formsAuth != null)
{
  FormsAuth = formsAuth;
}
else
{
  FormsAuth = new FormsAuthenticationWrapper();
}

如果您熟悉 Ruby,它的||=类似于 C#的??对我来说。这是一些 Ruby:

irb(main):001:0> str1 = nil
=> nil
irb(main):002:0> str1 ||= "new value"
=> "new value"
irb(main):003:0> str2 = "old value"
=> "old value"
irb(main):004:0> str2 ||= "another new value"
=> "old value"
irb(main):005:0> str1
=> "new value"
irb(main):006:0> str2
=> "old value"

在 C#中:

string str1 = null;
str1 = str1 ?? "new value";
string str2 = "old value";
str2 = str2 ?? "another new value";

合并运算符

相当于

FormsAuth = formsAUth == null ? new FormsAuthenticationWrapper() : formsAuth

没什么危险的。实际上,它是美丽的。如果需要,可以添加默认值,例如:

int x = x1 ?? x2 ?? x3 ?? x4 ?? 0;