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

Lan*_*eyo 309 c# operators c#-6.0

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

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

...

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

它到底是做什么用的?

Jon*_*eet 437

它是空条件运算符.它基本上意味着:

"评估第一个操作数;如果为null,则停止,结果为null.否则,计算第二个操作数(作为第一个操作数的成员访问权限)."

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

换句话说,它是这样的:

string bar = (a == null ? null : a.PropertyOfA);
if (bar != foo)
{
    ...
}
Run Code Online (Sandbox Code Playgroud)

...除了a仅评估一次.

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

FileInfo fi = ...; // fi could be null
long? length = fi?.Length; // If fi is null, length will be null
Run Code Online (Sandbox Code Playgroud)

  • 我更喜欢名字"猫王"操作员:P (8认同)
  • 是不是它被称为_null conditional_运算符? (6认同)
  • @SLaks:好的.在SyntaxKind中,它显然是ConditionalAccessExpression,令人烦恼的是它们都不是...... (3认同)
  • 仅仅为了记录我已经看到了这个运算符的五个不同的名称:安全导航,空条件,空传播,条件访问,猫王. (3认同)
  • 值得注意的是...您还可以在数组上使用 null 条件,例如:a?[x] (3认同)

Eri*_*ips 70

在展平层次结构和/或映射对象时,它非常有用.代替:

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;
}
Run Code Online (Sandbox Code Playgroud)

它可以写成(与上面相同的逻辑)

mapped.Name = Model.Model2?.Model3?.Model4?.Name ?? "N/A";
Run Code Online (Sandbox Code Playgroud)

DotNetFiddle.Net工作实例.

(??或null-coalescing运算符?或null条件运算符不同).

它也可以在Action的赋值运算符一侧使用.代替

Action<TValue> myAction = null;

if (myAction != null)
{
  myAction(TValue);
}
Run Code Online (Sandbox Code Playgroud)

它可以简化为:

myAction?.Invoke(TValue);
Run Code Online (Sandbox Code Playgroud)

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");
  }
}
Run Code Online (Sandbox Code Playgroud)

结果:

测试2

  • 为了拯救人们仰视什么?是..它是null-coalescing运算符,如果它不为null将返回Name,否则返回"N/A". (24认同)
  • @ErikPhilips:这与第一条评论无关,因为这与你的第一个例子无关.在这里你将跳转到`else`-branch并且有`mapped.Name = Model.Model2.Model3.Model4.Name - > mapped.Name = null`,而你的第二个例子将替换为`mapped.Name =" N/A"`.参见[编辑过的DotNetFiddle](https://dotnetfiddle.net/vunRkC) (7认同)
  • @Erik Philips我想你需要添加**`|| Model.Model2.Model3.Model4.Name == null`**具有相同的逻辑,否则如果`Model.Model2.Model3.Model4.Name`是'null`,`mapped.Name`将保持`null` (6认同)
  • @RazvanR请阅读有关??的先前评论。 (2认同)
  • @ErikPhilips我猜不在同一页面上。如果“ Model.Model2.Model3.Model4.Name”为“ null”,请尝试查看两种情况下的情况。 (2认同)

Zee*_*dil 6

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

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

var functionCaller = this.member;
if (functionCaller!= null)
    functionCaller.someFunction(var someParam);
Run Code Online (Sandbox Code Playgroud)

现在只需:

member?.someFunction(var someParam);
Run Code Online (Sandbox Code Playgroud)

我强烈推荐这个文档页面