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

问题描述 投票:0回答:3

在 VS2015 预览中使用 C# 6.0,我们有一个新的运算符,

?.
,可以像这样使用:

public class A {
   string PropertyOfA { get; set; }
}

...

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

它到底有什么作用?

c# operators c#-6.0
3个回答
722
投票

这是 null 条件 运算符。它的基本意思是:

“评估第一个操作数;如果它为空,则停止,结果为空。否则,评估第二个操作数(作为第一个操作数的成员访问)。”

在您的示例中,关键是如果

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

换句话说,就是这样的:

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

...除了

a
只评估一次。

请注意,这也可以更改表达式的类型。例如,考虑

FileInfo.Length
。这是
long
类型的属性,但是如果您将它与 null 条件运算符一起使用,您最终会得到一个
long?
:

类型的表达式
FileInfo fi = ...; // fi could be null
long? length = fi?.Length; // If fi is null, length will be null

130
投票

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

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 工作示例.

?? 或空合并运算符 不同于 ? 或空条件运算符)。

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

Action<TValue> myAction = null;

if (myAction != null)
{
  myAction(TValue);
}

可以简化为:

myAction?.Invoke(TValue);

DotNetFiddle 示例

使用系统;

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 operators on the left value,无论值的类型如何。并且编译器不关心右边的值是什么。它是简单的编译器 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


8
投票

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

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

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

现在它变得更容易了:

member?.someFunction(var someParam);

我强烈推荐这个文档页面.

© www.soinside.com 2019 - 2024. All rights reserved.