C#中两个问号共同意味着什么?

时间:2022-01-01 07:20:26

Ran across this line of code:

跨越这行代码:

FormsAuth = formsAuth ?? new FormsAuthenticationWrapper();

What do the two question marks mean, is it some kind of ternary operator?It's hard to look up in Google.

这两个问号意味着什么,它是某种三元运算符?在Google中很难查找。

16 个解决方案

#1


It's the null coalescing operator, and quite like the ternary (immediate-if) operator. See also ?? Operator - MSDN.

它是空合并运算符,非常类似于三元(立即if)运算符。也可以看看 ??运营商 - MSDN。

FormsAuth = formsAuth ?? new FormsAuthenticationWrapper();

expands to:

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

which further expands to:

进一步扩展到:

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

In English, it means "If whatever is to the left is not null, use that, otherwise use what's to the right."

在英语中,它表示“如果左边的任何内容不为空,请使用它,否则使用右边的内容。”

Note that you can use any number of these in sequence. The following statement will assign the first non-null Answer# to Answer (if all Answers are null then the Answer is null):

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

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

Also it's worth mentioning while the expansion above is conceptually equivalent, the result of each expression is only evaluated once. This is important if for example an expression is a method call with side effects. (Credit to @Joey for pointing this out.)

值得一提的是,虽然上面的扩展在概念上是等价的,但每个表达式的结果只评估一次。例如,如果表达式是带副作用的方法调用,则这很重要。 (感谢@Joey指出这一点。)

#2


Just because no-one else has said the magic words yet: it's the null coalescing operator. It's defined in section 7.12 of the C# 3.0 language specification.

仅仅因为没有其他人说过神奇的话:它是空的合并运算符。它在C#3.0语言规范的第7.12节中定义。

It's very handy, particularly because of the way it works when it's used multiple times in an expression. An expression of the form:

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

a ?? b ?? c ?? d

will give the result of expression a if it's non-null, otherwise try b, otherwise try c, otherwise try d. It short-circuits at every point.

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

Also, if the type of d is non-nullable, the type of the whole expression is non-nullable too.

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

#3


It's the null coalescing operator.

它是空合并运算符。

http://msdn.microsoft.com/en-us/library/ms173224.aspx

Yes, nearly impossible to search for unless you know what it's called! :-)

是的,几乎不可能搜索,除非你知道它叫什么! :-)

EDIT: And this is a cool feature from another question. You can chain them.

编辑:这是另一个问题的一个很酷的功能。你可以链接它们。

Hidden Features of C#?

C#的隐藏功能?

#4


Thanks everybody, here is the most succinct explanation I found on the MSDN site:

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

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

#5


?? is there to provide a value for a nullable type when the value is null. So, if formsAuth is null, it will return new FormsAuthenticationWrapper().

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

#6


C#中两个问号共同意味着什么?

The two question marks (??) indicate that its a Coalescing operator.

两个问号(??)表示它是一个Coalescing运算符。

Coalescing operator returns the first NON-NULL value from a chain. You can see this youtube video which demonstrates the whole thing practically.

Coalescing运算符返回链中的第一个NON-NULL值。你可以看到这个youtube视频,它实际上展示了整个事物。

But let me add more to what the video says.

但是,让我为视频所说的内容添加更多内容。

If you see the English meaning of coalescing it says “consolidate together”. For example below is a simple coalescing code which chains four strings.

如果你看到合并的英文含义,就说“合并在一起”。例如,下面是一个简单的合并代码,它链接了四个字符串。

So if str1 is null it will try str2, if str2 is null it will try str3 and so on until it finds a string with a non-null value.

因此,如果str1为null,它将尝试str2,如果str2为null,它将尝试str3,依此类推,直到找到具有非null值的字符串。

string final = str1 ?? str2 ?? str3 ?? str4;

In simple words Coalescing operator returns the first NON-NULL value from a chain.

简单来说,Coalescing运算符从链中返回第一个NON-NULL值。

#7


If you're familiar with Ruby, its ||= seems akin to C#'s ?? to me. Here's some Ruby:

如果你熟悉Ruby,它的|| =似乎类似于C#的?对我来说。这是一些Ruby:

irb(main):001:0> str1 = nil=> nilirb(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"

And in C#:

在C#中:

string str1 = null;str1 = str1 ?? "new value";string str2 = "old value";str2 = str2 ?? "another new value";

#8


It's short hand for the ternary operator.

这是三元运营商的捷径。

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

Or for those who don't do ternary:

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

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

#9


Nothing dangerous about this. In fact, it is beautiful. You can add default value if that is desirable, for example:

这没什么危险的。事实上,它是美丽的。如果需要,您可以添加默认值,例如:

CODE

int x = x1 ?? x2 ?? x3 ?? x4 ?? 0;

#10


For your amusement only (knowing you are all C# guys ;-).

只为了你的娱乐(知道你们都是C#伙伴;-)。

I think it originated in Smalltalk, where it has been around for many years. It is defined there as:

我认为它起源于Smalltalk,它已存在多年。它定义为:

in Object:

? anArgument    ^ self

in UndefinedObject (aka nil's class):

在UndefinedObject(又名nil的类)中:

? anArgument    ^ anArgument

There are both evaluating (?) and non-evaluating versions (??) of this.
It is often found in getter-methods for lazy-initialized private (instance) variables, which are left nil until really needed.

这有评估(?)和非评估版本(??)。在getter-methods中经常可以找到惰性初始化的私有(实例)变量,这些变量在真正需要之前保持为零。

#11


coalescing operator

it's equivalent to

它相当于

FormsAuth = formsAUth == null ? new FormsAuthenticationWrapper() : formsAuth

#12


Some of the examples here of getting values using coalescing are inefficient.

这里使用合并获取值的一些示例是低效的。

What you really want is:

你真正想要的是:

return _formsAuthWrapper = _formsAuthWrapper ?? new FormsAuthenticationWrapper();

or

return _formsAuthWrapper ?? (_formsAuthWrapper = new FormsAuthenticationWrapper());

This prevents the object from being recreated every time. Instead of the private variable remaining null and a new object getting created on every request, this ensures the private variable is assigned if the new object is created.

这可以防止每次都重新创建对象。而不是私有变量保持为null并且在每个请求上创建新对象,这确保在创建新对象时分配私有变量。

#13


As correctly pointed in numerous answers that is the "null coalescing operator" (??), speaking of which you might also want to check out its cousin the "Null-conditional Operator" (?. or ?[) that is an operator that many times it is used in conjunction with ??

正如许多答案中正确指出的那样是“空合并运算符”(??),说到你也可能想要查看它的表兄“Null-conditional Operator”(?。或?[),它是一个运算符很多次它与??一起使用

Null-conditional Operator

Used to test for null before performing a member access (?.) or index (?[) operation. These operators help you write less code to handle null checks, especially for descending into data structures.

用于在执行成员访问(?。)或索引(?[)操作之前测试null。这些运算符可帮助您编写更少的代码来处理空值检查,尤其是降序到数据结构中。

For example:

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

the old way without ?. and ?? of doing this is

旧的方式没有?和??做到这一点

int dollarAmount = customers != null                    && customers.Order!=null                   && customers.Order.Price!=null                     ? customers.Order.Price : 0; 

which is more verbose and cumbersome.

这更冗长,更麻烦。

#14


Note:

I have read whole this thread and many others but I can't find as thorough answer as this is.

我已经阅读了整个这个主题以及其他许多内容,但我找不到这样的全面答案。

By which I completely understood the "why to use ?? and when to use ?? and how to use ??."

通过它我完全理解“为什么要使用??以及何时使用??以及如何使用??”。

Source:

Windows communication foundation unleashed By Craig McMurtryISBN 0-672-32948-4

Windows通信基础由Craig McMurtryISBN 0-672-32948-4释放

Nullable Value Types

There are two common circumstances in which one would like to know whethera value has been assigned to an instance of a value type. The first is when the instance represents a value in a database. In such a case, one would like to be able to examine the instance to ascertain whether a value is indeed present in the database. The other circumstance, which is more pertinent to the subject matter of this book, is when the instance represents a data item received from some remote source. Again, one would like to determine from the instance whether a value for that data item was received.

在两种常见情况下,人们想知道是否已将值分配给值类型的实例。第一个是实例表示数据库中的值。在这种情况下,人们希望能够检查实例以确定数据库中是否确实存在值。另一种与本书主题相关的情况是,实例表示从某个远程源接收的数据项。同样,人们希望从实例确定是否收到该数据项的值。

The .NET Framework 2.0 incorporates a generic type definition that provides for cases like these in which one wants to assign null to an instance of a value type, and test whether the value of the instance is null. That generic type definition is System.Nullable, which constrains the generic type arguments that may be substituted for T to value types.Instances of types constructed from System.Nullable can be assigned a value of null; indeed, their values are null by default. Thus, types constructed fromSystem.Nullable may be referred to as nullable value types.System.Nullable has a property, Value, by which the value assigned to an instance ofa type constructed from it can be obtained if the value of the instance is not null.Therefore, one can write:

.NET Framework 2.0包含一个泛型类型定义,它提供了类似这样的情况,其中一个想要将null分配给值类型的实例,并测试实例的值是否为null。该泛型类型定义是System.Nullable,它约束可以用T替换值类型的泛型类型参数。从System.Nullable构造的类型的实例可以赋值为null;实际上,默认情况下它们的值为空。因此,从System.Nullable构造的类型可以称为可空值类型.System.Nullable具有一个属性Value,通过该属性Value,如果实例的值不为null,则可以获取分配给由其构造的类型实例的值。因此,人们可以写:

System.Nullable<int> myNullableInteger = null;myNullableInteger = 1;if (myNullableInteger != null){Console.WriteLine(myNullableInteger.Value);}

The C# programming language provides an abbreviated syntax for declaring typesconstructed from System.Nullable. That syntax allows one to abbreviate:

C#编程语言提供了一种缩写语法,用于声明从System.Nullable构造的类型。该语法允许缩写:

System.Nullable<int> myNullableInteger;

to

int? myNullableInteger;

The compiler will prevent one from attempting to assign the value of a nullable value type to an ordinary value type in this way:

编译器将阻止尝试以这种方式将可空值类型的值分配给普通值类型:

int? myNullableInteger = null;int myInteger = myNullableInteger;

It prevents one from doing so because the nullable value type could have the value null, which it actually would have in this case, and that value cannot be assigned to an ordinary value type. Although the compiler would permit this code,

它可以防止这样做,因为可以为null的值类型可以具有null值,在这种情况下它实际上具有该值,并且该值不能分配给普通值类型。虽然编译器会允许这段代码,

int? myNullableInteger = null;int myInteger = myNullableInteger.Value;

The second statement would cause an exception to be thrown because any attempt toaccess the System.Nullable.Value property is an invalid operation if the typeconstructed from System.Nullable has not been assigned a valid value of T, which has not happened in this case.

第二个语句将导致抛出异常,因为如果从System.Nullable构造的类型没有为T指定有效值(在这种情况下没有发生),则任何尝试访问System.Nullable.Value属性都是无效操作。

Conclusion:

One proper way to assign the value of a nullable value type to an ordinary value type is to use the System.Nullable.HasValue property to ascertain whether a valid value of T has been assigned to the nullable value type:

将可空值类型的值分配给普通值类型的一种正确方法是使用System.Nullable.HasValue属性来确定是否已将有效值T分配给可空值类型:

int? myNullableInteger = null;if (myNullableInteger.HasValue){int myInteger = myNullableInteger.Value;}

Another option is to use this syntax:

另一种选择是使用以下语法:

int? myNullableInteger = null;int myInteger = myNullableInteger ?? -1;

By which the ordinary integer myInteger is assigned the value of the nullable integer "myNullableInteger" if the latter has been assigned a valid integer value; otherwise, myInteger is assigned the value of -1.

通过为普通整数myInteger分配可空整数“myNullableInteger”的值,如果后者已被赋予有效整数值;否则,myInteger的值为-1。

#15


It's a null coalescing operator that works similarly to a ternary operator.

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

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

Another interesting point for this is,"A nullable type can contain a value, or it can be undefined".So if you try to assign a nullable value type to a non-nullable value type you will get a compile-time error.

另一个有趣的观点是,“可以为空的类型可以包含一个值,或者它可以是未定义的。”因此,如果您尝试将可空值类型分配给不可为空的值类型,则会出现编译时错误。

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

So to do that using ?? operator:

所以要用它来做?运营商:

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

#16


FormsAuth = formsAuth ?? new FormsAuthenticationWrapper();

is equivalent to

相当于

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

But the cool thing about it is you can chain them, like other people said.The one thin not touched upon is that you can actually use it to throw an exception.

但关于它的一个很酷的事情就是你可以像其他人所说的那样链接它们。没有涉及的一个很薄的是你实际上可以使用它来抛出异常。

A = A ?? B ?? throw new Exception("A and B are both NULL");

#1


It's the null coalescing operator, and quite like the ternary (immediate-if) operator. See also ?? Operator - MSDN.

它是空合并运算符,非常类似于三元(立即if)运算符。也可以看看 ??运营商 - MSDN。

FormsAuth = formsAuth ?? new FormsAuthenticationWrapper();

expands to:

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

which further expands to:

进一步扩展到:

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

In English, it means "If whatever is to the left is not null, use that, otherwise use what's to the right."

在英语中,它表示“如果左边的任何内容不为空,请使用它,否则使用右边的内容。”

Note that you can use any number of these in sequence. The following statement will assign the first non-null Answer# to Answer (if all Answers are null then the Answer is null):

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

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

Also it's worth mentioning while the expansion above is conceptually equivalent, the result of each expression is only evaluated once. This is important if for example an expression is a method call with side effects. (Credit to @Joey for pointing this out.)

值得一提的是,虽然上面的扩展在概念上是等价的,但每个表达式的结果只评估一次。例如,如果表达式是带副作用的方法调用,则这很重要。 (感谢@Joey指出这一点。)

#2


Just because no-one else has said the magic words yet: it's the null coalescing operator. It's defined in section 7.12 of the C# 3.0 language specification.

仅仅因为没有其他人说过神奇的话:它是空的合并运算符。它在C#3.0语言规范的第7.12节中定义。

It's very handy, particularly because of the way it works when it's used multiple times in an expression. An expression of the form:

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

a ?? b ?? c ?? d

will give the result of expression a if it's non-null, otherwise try b, otherwise try c, otherwise try d. It short-circuits at every point.

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

Also, if the type of d is non-nullable, the type of the whole expression is non-nullable too.

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

#3


It's the null coalescing operator.

它是空合并运算符。

http://msdn.microsoft.com/en-us/library/ms173224.aspx

Yes, nearly impossible to search for unless you know what it's called! :-)

是的,几乎不可能搜索,除非你知道它叫什么! :-)

EDIT: And this is a cool feature from another question. You can chain them.

编辑:这是另一个问题的一个很酷的功能。你可以链接它们。

Hidden Features of C#?

C#的隐藏功能?

#4


Thanks everybody, here is the most succinct explanation I found on the MSDN site:

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

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

#5


?? is there to provide a value for a nullable type when the value is null. So, if formsAuth is null, it will return new FormsAuthenticationWrapper().

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

#6


C#中两个问号共同意味着什么?

The two question marks (??) indicate that its a Coalescing operator.

两个问号(??)表示它是一个Coalescing运算符。

Coalescing operator returns the first NON-NULL value from a chain. You can see this youtube video which demonstrates the whole thing practically.

Coalescing运算符返回链中的第一个NON-NULL值。你可以看到这个youtube视频,它实际上展示了整个事物。

But let me add more to what the video says.

但是,让我为视频所说的内容添加更多内容。

If you see the English meaning of coalescing it says “consolidate together”. For example below is a simple coalescing code which chains four strings.

如果你看到合并的英文含义,就说“合并在一起”。例如,下面是一个简单的合并代码,它链接了四个字符串。

So if str1 is null it will try str2, if str2 is null it will try str3 and so on until it finds a string with a non-null value.

因此,如果str1为null,它将尝试str2,如果str2为null,它将尝试str3,依此类推,直到找到具有非null值的字符串。

string final = str1 ?? str2 ?? str3 ?? str4;

In simple words Coalescing operator returns the first NON-NULL value from a chain.

简单来说,Coalescing运算符从链中返回第一个NON-NULL值。

#7


If you're familiar with Ruby, its ||= seems akin to C#'s ?? to me. Here's some Ruby:

如果你熟悉Ruby,它的|| =似乎类似于C#的?对我来说。这是一些Ruby:

irb(main):001:0> str1 = nil=> nilirb(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"

And in C#:

在C#中:

string str1 = null;str1 = str1 ?? "new value";string str2 = "old value";str2 = str2 ?? "another new value";

#8


It's short hand for the ternary operator.

这是三元运营商的捷径。

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

Or for those who don't do ternary:

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

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

#9


Nothing dangerous about this. In fact, it is beautiful. You can add default value if that is desirable, for example:

这没什么危险的。事实上,它是美丽的。如果需要,您可以添加默认值,例如:

CODE

int x = x1 ?? x2 ?? x3 ?? x4 ?? 0;

#10


For your amusement only (knowing you are all C# guys ;-).

只为了你的娱乐(知道你们都是C#伙伴;-)。

I think it originated in Smalltalk, where it has been around for many years. It is defined there as:

我认为它起源于Smalltalk,它已存在多年。它定义为:

in Object:

? anArgument    ^ self

in UndefinedObject (aka nil's class):

在UndefinedObject(又名nil的类)中:

? anArgument    ^ anArgument

There are both evaluating (?) and non-evaluating versions (??) of this.
It is often found in getter-methods for lazy-initialized private (instance) variables, which are left nil until really needed.

这有评估(?)和非评估版本(??)。在getter-methods中经常可以找到惰性初始化的私有(实例)变量,这些变量在真正需要之前保持为零。

#11


coalescing operator

it's equivalent to

它相当于

FormsAuth = formsAUth == null ? new FormsAuthenticationWrapper() : formsAuth

#12


Some of the examples here of getting values using coalescing are inefficient.

这里使用合并获取值的一些示例是低效的。

What you really want is:

你真正想要的是:

return _formsAuthWrapper = _formsAuthWrapper ?? new FormsAuthenticationWrapper();

or

return _formsAuthWrapper ?? (_formsAuthWrapper = new FormsAuthenticationWrapper());

This prevents the object from being recreated every time. Instead of the private variable remaining null and a new object getting created on every request, this ensures the private variable is assigned if the new object is created.

这可以防止每次都重新创建对象。而不是私有变量保持为null并且在每个请求上创建新对象,这确保在创建新对象时分配私有变量。

#13


As correctly pointed in numerous answers that is the "null coalescing operator" (??), speaking of which you might also want to check out its cousin the "Null-conditional Operator" (?. or ?[) that is an operator that many times it is used in conjunction with ??

正如许多答案中正确指出的那样是“空合并运算符”(??),说到你也可能想要查看它的表兄“Null-conditional Operator”(?。或?[),它是一个运算符很多次它与??一起使用

Null-conditional Operator

Used to test for null before performing a member access (?.) or index (?[) operation. These operators help you write less code to handle null checks, especially for descending into data structures.

用于在执行成员访问(?。)或索引(?[)操作之前测试null。这些运算符可帮助您编写更少的代码来处理空值检查,尤其是降序到数据结构中。

For example:

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

the old way without ?. and ?? of doing this is

旧的方式没有?和??做到这一点

int dollarAmount = customers != null                    && customers.Order!=null                   && customers.Order.Price!=null                     ? customers.Order.Price : 0; 

which is more verbose and cumbersome.

这更冗长,更麻烦。

#14


Note:

I have read whole this thread and many others but I can't find as thorough answer as this is.

我已经阅读了整个这个主题以及其他许多内容,但我找不到这样的全面答案。

By which I completely understood the "why to use ?? and when to use ?? and how to use ??."

通过它我完全理解“为什么要使用??以及何时使用??以及如何使用??”。

Source:

Windows communication foundation unleashed By Craig McMurtryISBN 0-672-32948-4

Windows通信基础由Craig McMurtryISBN 0-672-32948-4释放

Nullable Value Types

There are two common circumstances in which one would like to know whethera value has been assigned to an instance of a value type. The first is when the instance represents a value in a database. In such a case, one would like to be able to examine the instance to ascertain whether a value is indeed present in the database. The other circumstance, which is more pertinent to the subject matter of this book, is when the instance represents a data item received from some remote source. Again, one would like to determine from the instance whether a value for that data item was received.

在两种常见情况下,人们想知道是否已将值分配给值类型的实例。第一个是实例表示数据库中的值。在这种情况下,人们希望能够检查实例以确定数据库中是否确实存在值。另一种与本书主题相关的情况是,实例表示从某个远程源接收的数据项。同样,人们希望从实例确定是否收到该数据项的值。

The .NET Framework 2.0 incorporates a generic type definition that provides for cases like these in which one wants to assign null to an instance of a value type, and test whether the value of the instance is null. That generic type definition is System.Nullable, which constrains the generic type arguments that may be substituted for T to value types.Instances of types constructed from System.Nullable can be assigned a value of null; indeed, their values are null by default. Thus, types constructed fromSystem.Nullable may be referred to as nullable value types.System.Nullable has a property, Value, by which the value assigned to an instance ofa type constructed from it can be obtained if the value of the instance is not null.Therefore, one can write:

.NET Framework 2.0包含一个泛型类型定义,它提供了类似这样的情况,其中一个想要将null分配给值类型的实例,并测试实例的值是否为null。该泛型类型定义是System.Nullable,它约束可以用T替换值类型的泛型类型参数。从System.Nullable构造的类型的实例可以赋值为null;实际上,默认情况下它们的值为空。因此,从System.Nullable构造的类型可以称为可空值类型.System.Nullable具有一个属性Value,通过该属性Value,如果实例的值不为null,则可以获取分配给由其构造的类型实例的值。因此,人们可以写:

System.Nullable<int> myNullableInteger = null;myNullableInteger = 1;if (myNullableInteger != null){Console.WriteLine(myNullableInteger.Value);}

The C# programming language provides an abbreviated syntax for declaring typesconstructed from System.Nullable. That syntax allows one to abbreviate:

C#编程语言提供了一种缩写语法,用于声明从System.Nullable构造的类型。该语法允许缩写:

System.Nullable<int> myNullableInteger;

to

int? myNullableInteger;

The compiler will prevent one from attempting to assign the value of a nullable value type to an ordinary value type in this way:

编译器将阻止尝试以这种方式将可空值类型的值分配给普通值类型:

int? myNullableInteger = null;int myInteger = myNullableInteger;

It prevents one from doing so because the nullable value type could have the value null, which it actually would have in this case, and that value cannot be assigned to an ordinary value type. Although the compiler would permit this code,

它可以防止这样做,因为可以为null的值类型可以具有null值,在这种情况下它实际上具有该值,并且该值不能分配给普通值类型。虽然编译器会允许这段代码,

int? myNullableInteger = null;int myInteger = myNullableInteger.Value;

The second statement would cause an exception to be thrown because any attempt toaccess the System.Nullable.Value property is an invalid operation if the typeconstructed from System.Nullable has not been assigned a valid value of T, which has not happened in this case.

第二个语句将导致抛出异常,因为如果从System.Nullable构造的类型没有为T指定有效值(在这种情况下没有发生),则任何尝试访问System.Nullable.Value属性都是无效操作。

Conclusion:

One proper way to assign the value of a nullable value type to an ordinary value type is to use the System.Nullable.HasValue property to ascertain whether a valid value of T has been assigned to the nullable value type:

将可空值类型的值分配给普通值类型的一种正确方法是使用System.Nullable.HasValue属性来确定是否已将有效值T分配给可空值类型:

int? myNullableInteger = null;if (myNullableInteger.HasValue){int myInteger = myNullableInteger.Value;}

Another option is to use this syntax:

另一种选择是使用以下语法:

int? myNullableInteger = null;int myInteger = myNullableInteger ?? -1;

By which the ordinary integer myInteger is assigned the value of the nullable integer "myNullableInteger" if the latter has been assigned a valid integer value; otherwise, myInteger is assigned the value of -1.

通过为普通整数myInteger分配可空整数“myNullableInteger”的值,如果后者已被赋予有效整数值;否则,myInteger的值为-1。

#15


It's a null coalescing operator that works similarly to a ternary operator.

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

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

Another interesting point for this is,"A nullable type can contain a value, or it can be undefined".So if you try to assign a nullable value type to a non-nullable value type you will get a compile-time error.

另一个有趣的观点是,“可以为空的类型可以包含一个值,或者它可以是未定义的。”因此,如果您尝试将可空值类型分配给不可为空的值类型,则会出现编译时错误。

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

So to do that using ?? operator:

所以要用它来做?运营商:

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

#16


FormsAuth = formsAuth ?? new FormsAuthenticationWrapper();

is equivalent to

相当于

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

But the cool thing about it is you can chain them, like other people said.The one thin not touched upon is that you can actually use it to throw an exception.

但关于它的一个很酷的事情就是你可以像其他人所说的那样链接它们。没有涉及的一个很薄的是你实际上可以使用它来抛出异常。

A = A ?? B ?? throw new Exception("A and B are both NULL");