我有一个空列表,尝试 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)
ans2和ans3不是一样的吗?
它们不是: null 条件运算符?.在遇到第一个 null 时停止对链式序列从左到右的求值,并将整个表达式解析为 null
ans1失败是因为您调用了 上的方法null。这崩溃了ans2失败,因为list为 null,?.看到它为 null 并将表达式解析为 null(ToList()从未被调用),因此null存储在temp. 然后,您尝试调用FirstOrDefaulta ,它会因与尝试null temp相同的原因而崩溃ans1ans3通过,因为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,那么它后面的任何东西都不会被调用