在这行代码中运行:

FormsAuth = formsAuth ?? new FormsAuthenticationWrapper();

这两个问号是什么意思,是某种三元运算符吗?在谷歌里很难查到。


当前回答

仅供消遣(知道你们都是C#家伙;-)。

我认为它起源于Smalltalk,在那里它已经存在了很多年。其定义如下:

在对象中:

? anArgument
    ^ self

在UndefinedObject(也称为nil的类)中:

? anArgument
    ^ anArgument

这既有评估版(?),也有非评估版本(??)。它经常出现在惰性初始化的私有(实例)变量的getter方法中,在真正需要之前,这些变量保持为零。

其他回答

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

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

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

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

a ?? b ?? c ?? d

将给出表达式a的结果,如果它是非空的,否则尝试b,否则尝试c,否则尝试d。它在每个点都短路。

此外,如果d的类型不可为null,则整个表达式的类型也不可为空。

仅供消遣(知道你们都是C#家伙;-)。

我认为它起源于Smalltalk,在那里它已经存在了很多年。其定义如下:

在对象中:

? anArgument
    ^ self

在UndefinedObject(也称为nil的类)中:

? anArgument
    ^ anArgument

这既有评估版(?),也有非评估版本(??)。它经常出现在惰性初始化的私有(实例)变量的getter方法中,在真正需要之前,这些变量保持为零。

它是一个空合并运算符,其工作方式与三元运算符类似。

    a ?? b  => a !=null ? a : b 

另一个有趣的点是,“可为null的类型可以包含值,也可以是未定义的”。因此,如果尝试将可为null的值类型分配给不可为null值类型您将得到一个编译时错误。

int? x = null; // x is nullable value type
int z = 0; // z is non-nullable value type
z = x; // compile error will be there.

所以要使用??操作员:

z = x ?? 1; // with ?? operator there are no issues

它是空合并运算符,非常像三元(立即if)运算符。另见??操作员-MSDN。

FormsAuth = formsAuth ?? new FormsAuthenticationWrapper();

扩展到:

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

其进一步扩展到:

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

在英语中,它的意思是“如果左边的东西不是空的,就用那个,否则就用右边的东西。”

请注意,您可以按顺序使用任意数量的这些。以下语句将为Answer分配第一个非空的Answer#(如果所有Answer均为空,则Answer为空):

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

另外值得一提的是,虽然上面的展开在概念上是等价的,但每个表达式的结果只计算一次。例如,如果表达式是具有副作用的方法调用,这一点很重要。(感谢@Joey指出了这一点。)