Resharper -可能将Null赋值给非空属性时的假阳性警告
本文关键字:属性 警告 Null 赋值 Resharper | 更新日期: 2023-09-27 18:05:06
在下面的代码中,Resharper标记了对key
的最后两个引用,尽管Resharper应该知道key
不会为空。
首先,检查string属性是否为Null、Empty或Whitespace,如果这些条件中的任何一个为真,则跳过该块。扩展方法,ToLowerNullSafe()
将只返回Null,如果输入是Null -这是一个标注(第二个代码块)。因为我们已经检查了属性是非空的,并且扩展方法被标记为返回非空,所以我希望Resharper知道key
是非空的。
var myObj = new { MyProperty = "some string" };
var myCache = new Dictionary<string, object>();
if (!string.IsNullOrWhiteSpace(myObj.MyProperty))
{
string key = myObj.MyProperty.ToLowerNullSafe();
lock (myCache)
{
if (!myCache.ContainsKey(key))
{
myCache.Add(key, myObj);
}
}
}
上面这两行是标记key
的地方:
if (!myCache.ContainsKey(key))
和
myCache.Add(key, myObj);
下面是ToLowerNullSafe方法及其注释。
[ContractAnnotation("null => null; notnull => notnull")]
public static string ToLowerNullSafe(this string str)
{
return string.IsNullOrWhiteSpace(str) ? str : str.ToLower();
}
关于为什么Resharper似乎忽略了注释,有什么想法吗?我该如何修复它?
使用:- Visual Studio Ultimate 2013 Update 5
- Resharper 8.2.3
- Nuget的当前注释(代码和外部)应用于项目。
- 。净4.5.2
编辑
myObj.MyProperty
的冗余空检查在!string.IsNullOrWhiteSpace
检查之前或之后添加一个冗余空检查(myObj.MyProperty != null
)来清除错误。
if (myObj.MyProperty != null && !string.IsNullOrWhiteSpace(myObj.MyProperty))
{
string key = myObj.MyProperty.ToLowerNullSafe();
lock (myCache)
{
if (!myCache.ContainsKey(key))
{
myCache.Add(key, myObj);
}
}
}
key
的冗余空检查添加冗余检查、断言或契约假设也可以清除错误。
这里我在给key
赋值后立即添加了Contract.Assume(key != null);
。
if (!string.IsNullOrWhiteSpace(myObj.MyProperty))
{
string key = myObj.MyProperty.ToLowerNullSafe();
Contract.Assume(key != null);
lock (myCache)
{
if (!myCache.ContainsKey(key))
{
myCache.Add(key, myObj);
}
}
}
不调用ToLowerNullSafe
这也清除了错误。但是,由于ContainsKey
方法执行区分大小写的比较,而我希望进行不区分大小写的比较,因此可能会出现问题。
if (!string.IsNullOrWhiteSpace(myObj.MyProperty))
{
string key = myObj.MyProperty;
lock (myCache)
{
if (!myCache.ContainsKey(key))
{
myCache.Add(key, myObj);
}
}
}
调用内置字符串函数ToLower
这也清除了错误。但会使代码库不一致。我们在代码中有很多地方可以预期空值,并且必须安全地处理,因此为了避免问题,我们在代码中应用了自定义...NullSafe
扩展方法。我不确定这是否符合"最佳实践",但这就是我们在这个项目中所做的。
if (!string.IsNullOrWhiteSpace(myObj.MyProperty))
{
string key = myObj.MyProperty.ToLower();
lock (myCache)
{
if (!myCache.ContainsKey(key))
{
myCache.Add(key, myObj);
}
}
}
在所有的工作代码示例中,Resharper似乎忽略了ToLowerNullSafe
扩展方法上的契约注释。然而,在第一个工作示例中,它确实识别了这些注释,但是通过对对象的属性使用显式的和冗余的null检查。
你能试一下吗
[ContractAnnotation("str:null => null; str:notnull=>notnull")]
我正在搜索为什么Resharper会这样做并发现这个页面,它也可能是Resharper的版本问题?
编辑
我已经实现了与您相同的功能,并完全从您的代码中创建了扩展方法,当我使用注释执行以下操作时,弯曲的线消失在"键"上。
[ContractAnnotation("null => true; notnull => true")]
希望对你有帮助。
我怀疑这是ReSharper 8中的一个bug(特别是考虑到@sarel- low的答案,它在合同中返回字符串返回值的bool值)。我刚刚在ReSharper 2016.2中尝试过,它根本不标记key
变量- ContractAnnotation
不需要。