当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《C#中两个问号共同意味着什么?》经验,为你挑选了14个好方法。

跨越这行代码:

FormsAuth = formsAuth ?? new FormsAuthenticationWrapper();

这两个问号意味着什么,是某种三元运算符?谷歌很难找到.



1> lc...:

它是空合并运算符,非常类似于三元(立即if)运算符.另见?? 运营商 - MSDN.

FormsAuth = formsAuth ?? new FormsAuthenticationWrapper();

扩展为:

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

进一步扩展到:

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

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

请注意,您可以按顺序使用任意数量的这些.下面的语句将指定第一个非空Answer#Answer(如果所有答案都为空,则Answer是空):

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

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


我不知道可以将这些链接起来
@CodeBlend,这并不危险.如果你要扩展,你只需要一系列嵌套的if/else语句.语法很奇怪,因为你不习惯看到它.
如果它也适用于空字符串,它本来就是神派:)
将这些链接起来可能具有潜在的危险性
@Gusdor` ??`是关联的,所以`a ?? b ?? C ??d`相当于`((a ?? b)?? c)?? D'."赋值运算符和三元运算符(?:)是右关联的.所有其他二元运算符都是左关联的." 来源:http://msdn.microsoft.com/en-us/library/ms173145.aspx
@CodeBlend怎么样?
@Zyphrax,是的.类似于`||`在JavaScript中的工作方式.
如果第一个参数第一次返回not-null,它会被评估两次吗?例如:x = f1()?? F2(); 当'f1'第一次返回not-null时会被评估两次吗?
@ Xitcod13不,不会.在语义上,你必须做`Answer1 ?? = Answer2`为Answer1赋值,但`?? =`不是一个有效的运算符.
请注意,这种扩展并不十分正确,如此处所示,因为该语言保证左操作数仅被评估一次。在这种情况下,这不是问题,但是当您的表达式比左侧的局部变量复杂时,它就变得很重要。

2> Jon Skeet..:

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

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

a ?? b ?? c ?? d

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

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


我喜欢您将其含义简化为“空合并运算符”的方式。那就是我所需要的。
切向但相关:它现在在Swift中,但它是非常不同的:"Nil Coalescing Operator"https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/BasicOperators.html

3> Iain Holder..:

它是空合并运算符.

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

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

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

C#的隐藏功能?


至少现在,它很容易搜索,即使你不知道名字,我只是用Google搜索*"双问号c#"*

4> Edward Tangu..:

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

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


@vitule no,如果null合并运算符的第二个操作数是非可空的,那么结果是不可为空的(并且`-1`只是一个普通的`int`,它是不可为空的).
这暗示了一个重要的方面?? 运算符 - 它被引入以帮助处理可空类型.在您的示例中,"x"的类型为"int?" (可空的).
我认为代码片段应为:int?y = x ?? -1;

5> RedFilter..:

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



6> Shivprasad K..:

在此输入图像描述

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

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

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

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

所以,如果str1null,它会尝试str2,如果str2null,它会尝试str3依此类推,直到它找到一个非空值的字符串.

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

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



7> Benjamin Aut..:

这是三元运营商的捷径.

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

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

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


我只纠正了"三元"的拼写,但实际上你的运算符是条件运算符.它恰好是C#中唯一的三元运算符,但在某些时候它们可能会添加另一个运算符,此时"三元"将是模糊的,但"有条件的"不会.

8> Sarah Vessel..:

如果你熟悉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";


注意`??`只关心`null`,而Ruby中的`||`运算符,就像在大多数语言中一样,更多的是关于`null`,`false`,或任何可以被视为带有值的布尔值`false`(例如在某些语言中,``"`).这不是好事或坏事,只是差别.
`x || = y` desugars to like`x = x || y`,所以`??`实际上更类似于Ruby中的普通`||`.

9> aku..:

合并运算符

它相当于

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



10> 小智..:

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

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



11> brakeroo..:

正如许多答案中正确指出的那样是"空合并运算符"(??),说到你也可能想要查看它的表兄"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; 

这更冗长,更麻烦.



12> blabla999..:

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

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

在对象中:

? anArgument
    ^ self

在UndefinedObject(又名nil的类)中:

? anArgument
    ^ anArgument

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



13> KingOfHypocr..:

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

你真正想要的是:

return _formsAuthWrapper = _formsAuthWrapper ?? new FormsAuthenticationWrapper();

要么

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

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



14> Wiqi..:
注意:

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

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

资源:

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 myNullableInteger = null;
myNullableInteger = 1;
if (myNullableInteger != null)
{
Console.WriteLine(myNullableInteger.Value);
}

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

System.Nullable 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.

推荐阅读
谢谢巷议
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有