在这行代码中运行:

FormsAuth = formsAuth ?? new FormsAuthenticationWrapper();

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


当前回答

注:

我已经阅读了这篇文章和其他许多文章,但我找不到像这样彻底的答案。

由此,我完全理解了“为什么要使用?何时使用?以及如何使用?”

资料来源:

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。

其他回答

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

如果您熟悉Ruby,那么它的||=似乎类似于C#的??给我。这是一些红宝石:

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";

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

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

在对象中:

? anArgument
    ^ self

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

? anArgument
    ^ anArgument

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

其他人已经很好地描述了空合并运算符。在需要对null进行一次测试的情况下,缩短的语法??=可以增加可读性。

传统空测试:

if (myvariable == null)
{
    myvariable = new MyConstructor();
}

使用空合并运算符,这可以写成:

myvariable = myvariable ?? new MyConstructor();

其也可以用缩短的语法编写:

myvariable ??= new MyConstructor();

有些人觉得它更易读、简洁。

这是三元运算符的短手。

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

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

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