问号和点运算符是啥意思?在 C# 6.0 中是啥意思?

Posted

技术标签:

【中文标题】问号和点运算符是啥意思?在 C# 6.0 中是啥意思?【英文标题】:What does question mark and dot operator ?. mean in C# 6.0?问号和点运算符是什么意思?在 C# 6.0 中是什么意思? 【发布时间】:2015-04-05 18:52:55 【问题描述】:

在 VS2015 预览版中使用 C# 6.0,我们有一个新的运算符,?.,可以这样使用:

public class A 
   string PropertyOfA  get; set; 


...

var a = new A();
var foo = "bar";
if(a?.PropertyOfA != foo) 
   //somecode

它到底是做什么的?

【问题讨论】:

如果您有兴趣将可空的 bool bool ? 转换为 bool 值 - ***.com/questions/6075726/… 【参考方案1】:

在扁平化层次结构和/或映射对象时非常有用。而不是:

if (Model.Model2 == null
  || Model.Model2.Model3 == null
  || Model.Model2.Model3.Model4 == null
  || Model.Model2.Model3.Model4.Name == null)

  mapped.Name = "N/A"

else

  mapped.Name = Model.Model2.Model3.Model4.Name;

可以这样写(逻辑同上)

mapped.Name = Model.Model2?.Model3?.Model4?.Name ?? "N/A";

DotNetFiddle.Net Working Example.

(?? or null-coalescing operator 与 ? or null conditional operator 不同)。

它也可以在Action 的赋值运算符之外使用。而不是

Action<TValue> myAction = null;

if (myAction != null)

  myAction(TValue);

可以简化为:

myAction?.Invoke(TValue);

DotNetFiddle Example:

使用系统;

public class Program

  public static void Main()
  
    Action<string> consoleWrite = null;
    
    consoleWrite?.Invoke("Test 1");
    
    consoleWrite = (s) => Console.WriteLine(s);
    
    consoleWrite?.Invoke("Test 2");
  

结果:

测试 2

基本上,我已经申请了?。模型之后的运算符也是如此。我想知道它是否可以直接应用于模型还是仅适用于导航属性?

无论值的类型如何,左侧值上的 ? or null conditional operator 运算符。编译器并不关心右边的值是什么。这是一个简单的编译器magic(意味着它做了一些你已经可以做的事情,只是简化了原因)。

例如

  var a = model?.Value;

和说的一样

  var a = model == null ? null : model.Value;

在第二种情况下,检查 null 的评估与返回的值没有关联。 null 条件运算符 基本上只在左值为 null 时返回 null。

成员的类型(方法、字段、属性、构造函数).Value 无关紧要。

您的 DotNetFiddle 示例不起作用的原因是用于 .Net 4.7.2 的编译器与支持 null 条件运算符的 c# 版本不兼容。将其更改为 .Net 5,有效:

https://dotnetfiddle.net/7EWoO5

【讨论】:

为了拯救人们查找什么?? is.. 它是空合并运算符,如果不为空则返回 Name,否则返回“N/A”。 @Erik Philips 我认为您需要添加 || Model.Model2.Model3.Model4.Name == null 以具有相同的逻辑,否则如果Model.Model2.Model3.Model4.Namenullmapped.Name 将保持@ 987654342@ @ErikPhilips 我猜不在同一页面上。如果Model.Model2.Model3.Model4.Namenull,请尝试查看两种情况会发生什么。 结果为“N/A”,请再次阅读第一条评论。 DotNetFiddle.Net Working Example. @ErikPhilips:这与第一条评论无关,因为这与您的第一个示例无关。在这种情况下,您将跳转到else-分支并拥有mapped.Name = Model.Model2.Model3.Model4.Name -&gt; mapped.Name = null,而您的第二个示例将替换为mapped.Name = "N/A"。见edited DotNetFiddle【参考方案2】:

这对于 C# 来说相对较新,这使我们可以轻松地在方法链接中调用关于 null 或非 null 值的函数。

实现相同目标的旧方法是:

var functionCaller = this.member;
if (functionCaller!= null)
    functionCaller.someFunction(var someParam);

现在它变得更容易了:

member?.someFunction(var someParam);

我强烈推荐this doc page。

【讨论】:

快速提问..var user = db.Users.Where(m=&gt;m.id == id).FirstOrDefault(); Console.WriteLine(user?.id); 这是否有效或?. 仅适用于导航属性?请检查这个小提琴:dotnetfiddle.net/2BblBv【参考方案3】:

这是null conditional 运算符。它基本上意味着:

“计算第一个操作数;如果为 null,则停止,结果为 null。否则,计算第二个操作数(作为第一个操作数的成员访问)。”

在您的示例中,关键是如果anull,那么a?.PropertyOfA 将评估为null 而不是抛出异常 - 然后它将null 引用与foo 进行比较(使用字符串的==重载),发现它们不相等,执行将进入if语句的主体。

换句话说,是这样的:

string bar = (a == null ? null : a.PropertyOfA);
if (bar != foo)

    ...

...除了a 只计算一次。

请注意,这也可以更改表达式的类型。例如,考虑FileInfo.Length。这是long 类型的属性,但如果你将它与空条件运算符一起使用,你最终会得到long? 类型的表达式:

FileInfo fi = ...; // fi could be null
long? length = fi?.Length; // If fi is null, length will be null

【讨论】:

@SLaks:我认为这是“条件空值”,但我可能错了。上次我检查 Roslyn 语言功能文档时,它还没有被重命名为。也许来源是这里的权威 - 将检查。 @SLaks:当然。在 SyntaxKind 中,它显然是 ConditionalAccessExpression,它们都不是令人讨厌的...... 我更喜欢名字“猫王”运营商:P 为了记录,我已经看到了这个运算符的五个不同名称:安全导航、空条件、空传播、条件访问、猫王。 有用的注意...您还可以在数组上使用 null 条件,例如:a?[x]

以上是关于问号和点运算符是啥意思?在 C# 6.0 中是啥意思?的主要内容,如果未能解决你的问题,请参考以下文章

“?”是啥意思?在 Erlang 中是啥意思? [复制]

/=/ 在 Netezza 中是啥意思?

:= 运算符在 mysql 中是啥意思?

=> 运算符在 Swift 中是啥意思?

三元从句中连续两个问号是啥意思?

& 是啥意思。 (& 点)在 Ruby 中是啥意思?