我遇到了这行代码:
FormsAuth = formsAuth ?? new FormsAuthenticationWrapper();
这两个问号代表什么意思?是一种三元运算符吗?在谷歌上查找很困难。
我遇到了这行代码:
FormsAuth = formsAuth ?? new FormsAuthenticationWrapper();
这两个问号代表什么意思?是一种三元运算符吗?在谷歌上查找很困难。
这是空值合并运算符,类似于三元(立即- 如果)运算符。 另请参见?? 运算符 - 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 指出这一点。)??
是左结合的,所以 a ?? b ?? c ?? d
等价于 ((a ?? b) ?? c) ?? d
。 "赋值运算符和三元运算符(?:)是右结合的。所有其他二元运算符都是左结合的。" 来源:http://msdn.microsoft.com/en-us/library/ms173145.aspx - Mark E. Haase正是因为没有人说出魔法词语,所以我告诉你吧:这就是空值合并运算符。它在C# 3.0语言规范的第7.12节中定义。
它非常方便,特别是当它在表达式中使用多次时的工作方式。一个形如:
a ?? b ?? c ?? d
如果表达式a
不是空的,它将返回结果a
。否则它会尝试b
,然后尝试c
,最后尝试d
。在每个点上都进行短路处理。
此外,如果d
的类型不可为空,则整个表达式的类型也是不可为空的。
这是一个空值合并运算符。
http://msdn.microsoft.com/zh-cn/library/ms173224.aspx
如果你不知道它的名字,几乎不可能搜索到它!:-)
编辑:另一个问题有一个很酷的功能。你可以链接它们。
谢谢大家,以下是我在MSDN网站上找到的最简明扼要的解释:
// y = x, unless x is null, in which case y = -1.
int y = x ?? -1;
两个问号(??)表示这是一个合并运算符。
合并运算符从链中返回第一个非空值。您可以观看这个YouTube视频来实际演示整个过程。
但让我为视频所说的内容增加更多说明。
如果您查看合并的英文含义,它的意思是“巩固在一起”。例如下面是一个简单的合并代码,用于链接四个字符串。
因此,如果str1
为null
,它将尝试str2
,如果str2
为null
,它将尝试str3
等,直到找到一个具有非空值的字符串。
string final = str1 ?? str2 ?? str3 ?? str4;
简单来说,合并运算符从链中返回第一个非空值。
??
是用于在可为空类型的值为null时提供一个默认值。 因此,如果 formsAuth 为空,它将返回新的 FormsAuthenticationWrapper()。
这是三元运算符的缩写。
FormsAuth = (formsAuth != null) ? formsAuth : new FormsAuthenticationWrapper();
对于不使用条件运算符的人,可以这样写:
if (formsAuth != null)
{
FormsAuth = formsAuth;
}
else
{
FormsAuth = new FormsAuthenticationWrapper();
}
!= null
)和第二个formsAuth
(在?
之后)都可以更改;在null合并形式中,两者都隐含地采用了您提供的值。 - Bob Sammers其他人已经很好地描述了 Null Coalescing Operator
。在需要进行单个null测试的情况下,缩短的语法 ??=
可以增加可读性。
传统的null测试:
if (myvariable == null)
{
myvariable = new MyConstructor();
}
使用空值合并运算符,可以这样编写:
myvariable = myvariable ?? new MyConstructor();
也可以用缩写语法来写:
myvariable ??= new MyConstructor();
一些人发现它更易读且简洁。
一些人发现它更易读且简洁。
如果你熟悉 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";
x ||= y
被展开后变成 x = x || y
,因此在 Ruby 中 ??
实际上更类似于普通的 ||
。 - qerub??
只关心 null
,而在 Ruby 中,类似于大多数编程语言的 ||
运算符更关注 null
、false
或任何被视为布尔值为 false
的内容(例如在某些语言中是 ""
)。这不是好事或坏事,仅仅是一种差异。 - Tim S.众多回答中正确指出了"null合并运算符" (??),此外你可能还想查看其近亲 "Null-conditional Operator" (?. 或 ?[)。这是一种操作符,经常与??结合使用。
用于在执行成员访问(?.)或索引(?[)操作之前测试是否为空。这些操作符可以帮助你写更少的代码来处理空检查,特别是对于深入数据结构时。
例如:
// if 'customers' or 'Order' property or 'Price' property is null,
// dollarAmount will be 0
// otherwise dollarAmount will be equal to 'customers.Order.Price'
int dollarAmount = customers?.Order?.Price ?? 0;
做这件事的旧方法没有?.和??
int dollarAmount = customers != null
&& customers.Order!=null
&& customers.Order.Price!=null
? customers.Order.Price : 0;
更加冗长而且繁琐。
C# ??
|C# '??'
|C# "??"
并没有得到预期的结果。这个搜索引擎是否在测试 C# 是否为空,并表示,不是 - 它实际上是C#
- 这里是您的C#
结果 - 哎呀! - Piotr Kuladouble question mark c#
。 - user692942