C# 可空和 FirstOrDefault 失败

sar*_*nan 0 c# linq nullable

我有一个空列表,尝试 FirstOrDefault 在不同的编码风格中表现不同。试图理解其中的差异。下面的三个片段尝试做同样的事情。但ans3单独工作没有任何异常。ans2和ans3不是一样的吗?

        IList<int> list = null;

        var ans1 = list.FirstOrDefault(); //Fails

        var temp = list?.ToList();
        var ans2 = temp.FirstOrDefault(); //Fails

        var ans3 = list?.ToList().FirstOrDefault(); //Passes
        
Run Code Online (Sandbox Code Playgroud)

Cai*_*ard 8

ans2和ans3不是一样的吗?

它们不是: null 条件运算符?.在遇到第一个 null 时停止对链式序列从左到右的求值,并将整个表达式解析为 null

  • ans1失败是因为您调用了 上的方法null。这崩溃了
  • ans2失败,因为list为 null,?.看到它为 null 并将表达式解析为 null(ToList()从未被调用),因此null存储在temp. 然后,您尝试调用FirstOrDefaulta ,它会因与尝试null temp相同的原因而崩溃ans1
  • ans3通过,因为ToList或 都FirstOrDefault没有被调用。C# 发现为 nullans3后立即设置为 nulllist

您可以??结合使用以?.确保项目具有价值:

var temp = list?.ToList() ?? new List<Thing>();
Run Code Online (Sandbox Code Playgroud)

如果?.检查list并发现它为空,则list?.ToList()解析为null??然后将采取行动,确保表达式解析为空List。这样调用方法是安全的..

空条件可以多次使用:

ans3 = someObject?.Any?.Of()?.These?.PropsOrMethods?.Could()?.Be?.Null
Run Code Online (Sandbox Code Playgroud)

如果该链中的任何属性或方法返回,则一旦遇到 null ,null整个事情就会发生,无论它位于链中的哪个位置。null如果 null 的东西是These,那么它后面的任何东西都不会被调用