跨越这行代码:
FormsAuth = formsAuth ?? new FormsAuthenticationWrapper();
这两个问号意味着什么,是某种三元运算符?在Google中查找起来很困难 .
它是空合并运算符 .
http://msdn.microsoft.com/en-us/library/ms173224.aspx
是的,几乎不可能搜索,除非你知道它叫什么! :-)
编辑:这是另一个问题的一个很酷的功能 . 你可以链接它们 .
Hidden Features of C#?
谢谢大家,这是我在MSDN网站上找到的最简洁的解释:
// y = x, unless x is null, in which case y = -1. int y = x ?? -1;
当值为null时, ?? 为可空类型提供值 . 因此,如果formsAuth为null,它将返回新的FormsAuthenticationWrapper() .
??
它是空合并运算符,非常类似于三元(立即if)运算符 . 另见?? Operator - MSDN .
扩展为:
FormsAuth = formsAuth != null ? formsAuth : new FormsAuthenticationWrapper();
进一步扩展到:
if(formsAuth != null) FormsAuth = formsAuth; else FormsAuth = new FormsAuthenticationWrapper();
在英语中,它表示“如果左边的任何内容不为空,请使用它,否则使用右边的内容 . ”
请注意,您可以按顺序使用任意数量的这些 . 以下语句将第一个非null Answer# 分配给 Answer (如果所有Answers都为null,则 Answer 为null):
Answer#
Answer
string Answer = Answer1 ?? Answer2 ?? Answer3 ?? Answer4;
值得一提的是,虽然上面的扩展在概念上是等价的,但每个表达式的结果只评估一次 . 例如,如果表达式是带副作用的方法调用,则这很重要 . (感谢@Joey指出这一点 . )
仅仅因为没有其他人说过神奇的话:它就是 null coalescing operator . 它在C# 3.0 language specification的第7.12节中定义 .
它非常方便,特别是因为它在表达式中多次使用时的工作方式 . 形式的表达式:
a ?? b ?? c ?? d
如果它是非空的,将给出表达式 a 的结果,否则尝试 b ,否则尝试 c ,否则尝试 d . 它在每个点都短路 .
a
b
c
d
此外,如果 d 的类型不可为空,则整个表达式的类型也是不可为空的 .
两个问号(??)表示它是一个Coalescing运算符 .
Coalescing运算符返回链中的第一个NON-NULL值 . 你可以看到this youtube video,它实际上展示了整个事物 .
但是,让我为视频所说的内容添加更多内容 .
如果你看到合并的英文含义,就说“合并在一起” . 例如,下面是一个链接四个字符串的简单合并代码 .
因此,如果 str1 是 null ,它将尝试 str2 ,如果 str2 是 null ,它将尝试 str3 ,依此类推,直到找到具有非空值的字符串 .
str1
null
str2
str3
string final = str1 ?? str2 ?? str3 ?? str4;
简单来说,Coalescing运算符从链中返回第一个NON-NULL值 .
如果你熟悉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) ? formsAuth : new FormsAuthenticationWrapper();
或者对于那些不做三元的人:
if (formsAuth != null) { FormsAuth = formsAuth; } else { FormsAuth = new FormsAuthenticationWrapper(); }
这没什么危险的 . 事实上,它是美丽的 . 如果需要,您可以添加默认值,例如:
CODE
int x = x1 ?? x2 ?? x3 ?? x4 ?? 0;
只为了你的娱乐(知道你们都是C#伙伴;-) .
我认为它起源于Smalltalk,它已存在多年 . 它定义为:
在对象中:
? anArgument ^ self
在UndefinedObject(又名nil的类)中:
? anArgument ^ anArgument
这有评估(?)和非评估版本(??) .在getter-methods中经常可以找到惰性初始化的私有(实例)变量,这些变量在真正需要之前保持为零 .
合并运算符
它相当于
FormsAuth = formsAUth == null ? new FormsAuthenticationWrapper() : formsAuth
这里使用合并获取值的一些示例是低效的 .
你真正想要的是:
return _formsAuthWrapper = _formsAuthWrapper ?? new FormsAuthenticationWrapper();
要么
return _formsAuthWrapper ?? (_formsAuthWrapper = new FormsAuthenticationWrapper());
这可以防止每次都重新创建对象 . 而不是私有变量保持为null并且在每个请求上创建新对象,这确保在创建新对象时分配私有变量 .
正如许多答案中正确指出的那样是"null coalescing operator"( ?? ),说到你可能还想看看它的堂兄"Null-conditional Operator"( ?. 或 ?[ )这是一个多次与 ?? 一起使用的算子
Null-conditional Operator
用于在执行成员访问(? . )或索引(?[)操作之前测试null . 这些运算符可帮助您编写更少的代码来处理空值检查,尤其是降序到数据结构中 .
例如:
// 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;
这更冗长,更麻烦 .
我已经阅读了整个这个帖子以及其他许多内容,但我找不到这样的彻底答案 .
通过它我完全理解“为什么要使用??以及何时使用??以及如何使用??” .
Windows通信基础由Craig McMurtry发布,ISBN 0-672-32948-4
有两种常见的情况哪一个想知道是否已将值分配给值类型的实例 . 第一个是实例表示数据库中的值 . 在这种情况下,人们希望能够检查实例以确定数据库中是否确实存在值 . 另一种与本书主题相关的情况是,实例表示从某个远程源接收的数据项 . 同样,人们希望从实例确定是否收到该数据项的值 .
.NET Framework 2.0包含一个泛型类型定义,它提供了类似这样的情况,其中一个人想要将null分配给值类型的实例,并测试实例的值是否为null . 该泛型类型定义是System.Nullable,它约束可以替换T到值类型的泛型类型参数 . 从System.Nullable构造的类型实例可以赋值为null;实际上,默认情况下它们的值为空 . 因此,从System.Nullable构造的类型可以称为可空值类型 . System.Nullable具有一个属性Value,通过该属性,如果实例的值不为null,则可以获取分配给从其构造的类型的实例的值 . 因此,人们可以写:
System.Nullable<int> myNullableInteger = null; myNullableInteger = 1; if (myNullableInteger != null) { Console.WriteLine(myNullableInteger.Value); }
C#编程语言提供了一种缩写语法,用于声明从System.Nullable构造的类型 . 该语法允许缩写:
System.Nullable<int> myNullableInteger;
至
int? myNullableInteger;
编译器将阻止尝试以这种方式将可空值类型的值分配给普通值类型:
int? myNullableInteger = null; int myInteger = myNullableInteger;
它可以防止这样做,因为可以为null的值类型可以具有null值,在这种情况下它实际上具有该值,并且该值不能分配给普通值类型 . 虽然编译器会允许这段代码,
int? myNullableInteger = null; int myInteger = myNullableInteger.Value;
第二个语句将导致抛出异常,因为如果从System.Nullable构造的类型没有被赋予有效的T值,那么任何访问System.Nullable.Value属性的尝试都是无效的操作,这在T中没有发生案件 .
将可空值类型的值分配给普通值类型的一种正确方法是使用System.Nullable.HasValue属性来确定是否已将有效值T分配给可空值类型:
int? myNullableInteger = null; if (myNullableInteger.HasValue) { int myInteger = myNullableInteger.Value; }
另一种选择是使用以下语法:
int? myNullableInteger = null; int myInteger = myNullableInteger ?? -1;
通过为普通整数myInteger分配可空整数“myNullableInteger”的值,如果后者已被赋予有效整数值;否则,myInteger的值为-1 .
它是一个空的合并运算符,与三元运算符的工作方式类似 .
a ?? b => a !=null ? a : b
另一个有趣的观点是,"A nullable type can contain a value, or it can be undefined" . 因此,如果您尝试将可空值类型分配给不可为空的值类型,则会出现编译时错误 .
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
相当于
但关于它的一个很酷的事情是你可以链接它们,就像其他人说的那样 . 没有触及的一个很薄的是你实际上可以使用它来抛出异常 .
A = A ?? B ?? throw new Exception("A and B are both NULL");
16 回答
它是空合并运算符 .
http://msdn.microsoft.com/en-us/library/ms173224.aspx
是的,几乎不可能搜索,除非你知道它叫什么! :-)
编辑:这是另一个问题的一个很酷的功能 . 你可以链接它们 .
Hidden Features of C#?
谢谢大家,这是我在MSDN网站上找到的最简洁的解释:
当值为null时,
??
为可空类型提供值 . 因此,如果formsAuth为null,它将返回新的FormsAuthenticationWrapper() .它是空合并运算符,非常类似于三元(立即if)运算符 . 另见?? Operator - MSDN .
扩展为:
进一步扩展到:
在英语中,它表示“如果左边的任何内容不为空,请使用它,否则使用右边的内容 . ”
请注意,您可以按顺序使用任意数量的这些 . 以下语句将第一个非null
Answer#
分配给Answer
(如果所有Answers都为null,则Answer
为null):值得一提的是,虽然上面的扩展在概念上是等价的,但每个表达式的结果只评估一次 . 例如,如果表达式是带副作用的方法调用,则这很重要 . (感谢@Joey指出这一点 . )
仅仅因为没有其他人说过神奇的话:它就是 null coalescing operator . 它在C# 3.0 language specification的第7.12节中定义 .
它非常方便,特别是因为它在表达式中多次使用时的工作方式 . 形式的表达式:
如果它是非空的,将给出表达式
a
的结果,否则尝试b
,否则尝试c
,否则尝试d
. 它在每个点都短路 .此外,如果
d
的类型不可为空,则整个表达式的类型也是不可为空的 .两个问号(??)表示它是一个Coalescing运算符 .
Coalescing运算符返回链中的第一个NON-NULL值 . 你可以看到this youtube video,它实际上展示了整个事物 .
但是,让我为视频所说的内容添加更多内容 .
如果你看到合并的英文含义,就说“合并在一起” . 例如,下面是一个链接四个字符串的简单合并代码 .
因此,如果
str1
是null
,它将尝试str2
,如果str2
是null
,它将尝试str3
,依此类推,直到找到具有非空值的字符串 .简单来说,Coalescing运算符从链中返回第一个NON-NULL值 .
如果你熟悉Ruby,它的
||=
似乎就像C#的??
一样 . 这是一些Ruby:在C#中:
这是三元运营商的捷径 .
或者对于那些不做三元的人:
这没什么危险的 . 事实上,它是美丽的 . 如果需要,您可以添加默认值,例如:
CODE
只为了你的娱乐(知道你们都是C#伙伴;-) .
我认为它起源于Smalltalk,它已存在多年 . 它定义为:
在对象中:
在UndefinedObject(又名nil的类)中:
这有评估(?)和非评估版本(??) .
在getter-methods中经常可以找到惰性初始化的私有(实例)变量,这些变量在真正需要之前保持为零 .
合并运算符
它相当于
这里使用合并获取值的一些示例是低效的 .
你真正想要的是:
要么
这可以防止每次都重新创建对象 . 而不是私有变量保持为null并且在每个请求上创建新对象,这确保在创建新对象时分配私有变量 .
正如许多答案中正确指出的那样是"null coalescing operator"( ?? ),说到你可能还想看看它的堂兄"Null-conditional Operator"( ?. 或 ?[ )这是一个多次与 ?? 一起使用的算子
Null-conditional Operator
例如:
没有 ?. 和 ?? 这样做的旧方法是
这更冗长,更麻烦 .
注意:
我已经阅读了整个这个帖子以及其他许多内容,但我找不到这样的彻底答案 .
通过它我完全理解“为什么要使用??以及何时使用??以及如何使用??” .
来源:
Windows通信基础由Craig McMurtry发布,ISBN 0-672-32948-4
可空值类型
有两种常见的情况哪一个想知道是否已将值分配给值类型的实例 . 第一个是实例表示数据库中的值 . 在这种情况下,人们希望能够检查实例以确定数据库中是否确实存在值 . 另一种与本书主题相关的情况是,实例表示从某个远程源接收的数据项 . 同样,人们希望从实例确定是否收到该数据项的值 .
.NET Framework 2.0包含一个泛型类型定义,它提供了类似这样的情况,其中一个人想要将null分配给值类型的实例,并测试实例的值是否为null . 该泛型类型定义是System.Nullable,它约束可以替换T到值类型的泛型类型参数 . 从System.Nullable构造的类型实例可以赋值为null;实际上,默认情况下它们的值为空 . 因此,从System.Nullable构造的类型可以称为可空值类型 . System.Nullable具有一个属性Value,通过该属性,如果实例的值不为null,则可以获取分配给从其构造的类型的实例的值 . 因此,人们可以写:
C#编程语言提供了一种缩写语法,用于声明从System.Nullable构造的类型 . 该语法允许缩写:
至
编译器将阻止尝试以这种方式将可空值类型的值分配给普通值类型:
它可以防止这样做,因为可以为null的值类型可以具有null值,在这种情况下它实际上具有该值,并且该值不能分配给普通值类型 . 虽然编译器会允许这段代码,
第二个语句将导致抛出异常,因为如果从System.Nullable构造的类型没有被赋予有效的T值,那么任何访问System.Nullable.Value属性的尝试都是无效的操作,这在T中没有发生案件 .
结论:
将可空值类型的值分配给普通值类型的一种正确方法是使用System.Nullable.HasValue属性来确定是否已将有效值T分配给可空值类型:
另一种选择是使用以下语法:
通过为普通整数myInteger分配可空整数“myNullableInteger”的值,如果后者已被赋予有效整数值;否则,myInteger的值为-1 .
它是一个空的合并运算符,与三元运算符的工作方式类似 .
另一个有趣的观点是,"A nullable type can contain a value, or it can be undefined" . 因此,如果您尝试将可空值类型分配给不可为空的值类型,则会出现编译时错误 .
所以要做到这一点?? ??运营商:
相当于
但关于它的一个很酷的事情是你可以链接它们,就像其他人说的那样 . 没有触及的一个很薄的是你实际上可以使用它来抛出异常 .