在这行代码中运行:
FormsAuth = formsAuth ?? new FormsAuthenticationWrapper();
这两个问号是什么意思,是某种三元运算符吗?在谷歌里很难查到。
在这行代码中运行:
FormsAuth = formsAuth ?? new FormsAuthenticationWrapper();
这两个问号是什么意思,是某种三元运算符吗?在谷歌里很难查到。
当前回答
仅供消遣(知道你们都是C#家伙;-)。
我认为它起源于Smalltalk,在那里它已经存在了很多年。其定义如下:
在对象中:
? anArgument
^ self
在UndefinedObject(也称为nil的类)中:
? anArgument
^ anArgument
这既有评估版(?),也有非评估版本(??)。它经常出现在惰性初始化的私有(实例)变量的getter方法中,在真正需要之前,这些变量保持为零。
其他回答
它是空合并运算符。
http://msdn.microsoft.com/en-us/library/ms173224.aspx
是的,几乎不可能搜索,除非你知道它叫什么!:-)
编辑:这是另一个问题的一个很酷的特点。你可以把它们拴起来。
C#的隐藏功能?
注:
我已经阅读了这篇文章和其他许多文章,但我找不到像这样彻底的答案。
由此,我完全理解了“为什么要使用?何时使用?以及如何使用?”
资料来源:
Craig McMurtry发布的Windows通信基础为0-672-32948-4
可为空的值类型
有两种常见的情况,人们想知道值已分配给值类型的实例。第一种是当实例表示数据库中的值时。在这种情况下,希望能够检查实例以确定数据库中是否确实存在值。另一种与本书主题更相关的情况是,当实例表示从某个远程源接收的数据项时。同样,人们希望从实例中确定是否接收到该数据项的值。
.NETFramework2.0包含了一个通用类型定义,它提供了这样的情况,即希望为值类型的实例分配null,并测试该实例的值是否为null。该泛型类型定义是System.Nullable<T>,它将可以替换T的泛型类型参数约束为值类型。从System.Nullable<T>构造的类型的实例可以赋值为null;实际上,它们的值默认为空。因此,从System.Nullable<T>可以称为可为null的值类型。System.Nullable<T>具有一个属性Value,通过该属性值分配给如果实例的值不为空,则可以获得由其构造的类型。因此,可以这样写:
System.Nullable<int> myNullableInteger = null;
myNullableInteger = 1;
if (myNullableInteger != null)
{
Console.WriteLine(myNullableInteger.Value);
}
C#编程语言为声明类型提供了缩写语法由System.Nullable<T>构造。该语法允许缩写:
System.Nullable<int> myNullableInteger;
to
int? myNullableInteger;
编译器将防止试图以以下方式将可空值类型的值分配给普通值类型:
int? myNullableInteger = null;
int myInteger = myNullableInteger;
它阻止人们这样做,因为可为null的值类型可能具有null值,在这种情况下它实际上具有null值并且该值不能分配给普通值类型。尽管编译器将允许该代码,
int? myNullableInteger = null;
int myInteger = myNullableInteger.Value;
第二条语句将导致引发异常,因为如果类型为从System.Nullable<T>构造的函数未分配有效值T,在本例中未发生这种情况。
结论:
将可为null的值类型的值分配给普通值类型的一种适当方法是使用System.nullable<T>.HasValue属性来确定是否已将有效值T分配给可为null值类型:
int? myNullableInteger = null;
if (myNullableInteger.HasValue)
{
int myInteger = myNullableInteger.Value;
}
另一种选择是使用此语法:
int? myNullableInteger = null;
int myInteger = myNullableInteger ?? -1;
如果为普通整数myInteger分配了有效整数值,则为其分配可空整数“myNullableInteger”的值;否则,myInteger的值为-1。
它是空合并运算符,非常像三元(立即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指出了这一点。)
FormsAuth = formsAuth ?? new FormsAuthenticationWrapper();
相当于
FormsAuth = formsAuth != null ? formsAuth : new FormsAuthenticationWrapper();
但它很酷的一点是,你可以像其他人说的那样,把它们拴起来。没有提到的一点是,您实际上可以使用它来抛出异常。
A = A ?? B ?? throw new Exception("A and B are both NULL");
这个运算符称为空合并运算符。如果操作数不为空,则返回左侧操作数;否则返回右手操作数。
int? variable1 = null;
int variable2 = variable1 ?? 100;
如果variable1不为空,则将variable2设置为variable1的值;否则,如果variable1==null,则将variable2设置为100。