我正在使用ReSharper Ultimate 2016.2,但我也在之前的版本中看到了这一点。当我在FirstOrDefault
之后使用Any
时,ReSharper会向我发出警告,说明可能'System.NullReferenceException'。示例如下:
Foo[] items = GetItems();
var myName = "MyName";
if (items.Any(x => x.Name == myName))
{
var item = items.FirstOrDefault(x => x.Name == myName);
var name = item.Name; // Possible 'System.NullReferenceException'
}
警告是否正确,或上述代码是否安全?
我知道我可以禁用警告,但这不是重点。我想确保NullReferenceException
没有发生的可能性。由于我首先使用Any
进行检查,因此FirstOrDefault
应该返回一个项目。或者我错过了什么?
上面的代码只是MCVE。
更新
如评论中所述,代码可以进行优化(和简化)。问题不在于如何解决代码中的问题。但是,如果实际上可以发生NullReferenceException
,正如ReSharper所说的那样?
答案 0 :(得分:4)
这是因为FirstOrDefault
。如果条件不匹配,它将为类返回NULL。此时,ReSharper不会在帐户中使用Any
。
您应该通过调用First
答案 1 :(得分:1)
当您确定在逻辑上始终为true的if块内分配变量时,这就像编译器使用未分配变量时发出的错误。简单的说。尝试将代码分析到此级别是不可行的,因为静态分析器应该在编译时知道(或更好地理解)在运行时变量的状态
void Main()
{
int a;
Environment.CurrentDirectory = "C:\\temp";
if(Environment.CurrentDirectory == "C:\\temp")
a = 1;
// Error - Use of unassigned variable
Console.WriteLine(a);
}
在这里,人类的大脑可以看到没有办法不分配变量,(没有其他线程混淆相同的属性,你已经检查了关于属性行为的参考源)但是编译器应该分析具有相同深度的代码的含义,并且在这个时间点,我们没有那个。同样的规则适用于Resharper,他们缺乏必要的智能来完成所需的一切(现在)