Linq ReSharper-可能';System.NullReferenceException';无论如何
我正在使用ReSharper Ultimate 2016.2,但我在以前的版本中也看到了这一点。当我在Linq ReSharper-可能';System.NullReferenceException';无论如何,linq,resharper,nullreferenceexception,Linq,Resharper,Nullreferenceexception,我正在使用ReSharper Ultimate 2016.2,但我在以前的版本中也看到了这一点。当我在Any之后使用first或default时,ReSharper会给我一个警告,说可能是'System.NullReferenceException'。示例如下: Foo[] items = GetItems(); var myName = "MyName"; if (items.Any(x => x.Name == myName)) { var item = items.First
Any
之后使用first或default
时,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
应返回一项。还是我遗漏了什么
上面的代码只是一个简单的例子
更新:
如注释中所述,代码可以优化(并简化)。问题不在于如何解决代码中的问题。但如果真的像ReSharper所说的那样出现
NullReferenceException
,那是因为FirstOrDefault
。如果条件不匹配,它将为类返回NULL。此时,ReSharper不考虑任何
您应该首先调用
来替换它。这类似于当您确定在逻辑上始终为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,他们缺乏必要的智能来完成所有需要的事情(目前)那么使用任何工具都没有意义。如果是First或default,然后检查结果是否为null如果您如此确定,为什么要使用
或default
,而不是简单地使用First
?该工具无法分析所有代码路径和逻辑。@IvanStoev-是的,我应该可以先使用
。但问题更多的是,ReSharper是否真的知道我遗漏了什么。代码中是否存在NullReferenceException
?或者该工具只是没有分析到这种程度的代码?这就像编译器使用未赋值变量时发出的错误,当您在逻辑上始终为true的if块中分配了该变量时。简单地说。尝试将代码分析到此级别是不可行的,因为静态分析器应该在编译时知道变量在运行时的状态。顺便说一句,假设GetItems
返回对共享数组的引用,另一个线程将Foo
名称从“MyName”更新为“YourName”在任何
呼叫之后。FirstOrDefault
之后的结果是什么?NRE:)是的。也不能保证属性getter返回的值与传递给属性setter的值相同。或者,即使它是一个字段,也不能保证它不会在调用之间被另一个线程更改,等等。谢谢。正如我所怀疑的,但我担心我错过了什么。这是正确的答案FirstOrDefault
是唯一重要的事情。该方法有一个CanBeNull
注释,这就是为什么认为item
是可能的null
。