ReSharper:如何删除“可能的’System.NullReferenceException’”警告
这是一段代码:
IUser user = managerUser.GetUserById(UserId); if ( user==null ) throw new Exception(...); Quote quote = new Quote(user.FullName, user.Email);
这里一切都很好。 但是,如果我用以下内容替换“if”行:
ComponentException.FailIfTrue(user == null, "Can't find user with Id=" + UserId);
函数实现如下:
public abstract class ComponentException : ComponentException where T : ComponentException, new() { public static void FailIfTrue(bool expression, string message) { if (expression) { T t = new T(); t.SetErrorMessage(message); throw t; } } ... }
然后resharper生成一个警告:可能’System.NullReferenceException’指向’user’对象的第一次使用。
Q1。 为什么会产生这种exception? 据我所知,如果’user == null’,那么将生成exception并且执行将永远不会到达使用点。
Q2。 如何删除该警告? 请注意:1。我不想用注释来抑制此警告(我将有很多类似的部分,并且不想在’评论的garbase中转换我的源代码); 2.我不想更改resharper设置以将此问题从警告更改为’提示’的’建议’。
谢谢。
欢迎任何想法!
PS我正在使用resharper 5.1,MVSV 2008,C#
Q1:因为Resharper不进行路径分析。 它只是看到一个可能的null
引用并标记它。
Q2:你不能不做你已经提供的任何一件事。
Resharper仅查看当前的分析方法,并不会递归分析您调用的其他方法。
但是,您可以指导Resharper并给它一些关于某些方法的元信息。 它例如知道“Assert.IsNotNull(a)”,并将该信息考虑在内进行分析。 可以为Resharper创建外部注释文件,并为其提供有关某个库的额外信息,以便更好地进行分析。 也许这可能会提供一种解决问题的方法。
更多信息可以在这里找到。
可以在此处找到显示如何将其用于库Microsoft.Contracts的示例。
旧帖中的新答案……
这里有一些关于如何通过ContractAnnotation与Resharper一起使用CodeContract的代码示例:
[ContractAnnotation("value:null=>true")] public static bool IsNullOrEmpty(this string value) { return string.IsNullOrEmpty(value); }
这很简单……如果你在木头上发现了面包屑。 您也可以查看其他案例。
祝你今天愉快
如果存在空引用,您确实知道(或期望)此代码将引发exception:
ComponentException.FailIfTrue([...]);
但是,由于没有合同指定这一点,ReSharper必须假设这只是一个普通的方法调用,它可以返回而不会抛出任何exception。
使这个方法实现ReSharper契约,或者作为一个简单的解决方法(只影响调试模式,因此对于释放模式没有性能损失),就在FailIfTrue
调用之后:
Debug.Assert(user != null);
这将消除警告,并作为额外的奖励在调试模式下进行运行时检查,以确保在调用FailIfTrue
之后确实满足您所采取的条件。
这是由Resharper引擎引起的。 这些“可能的NullReferenceException”发生是因为有人(可能在Resharper)已经在方法上的某个地方声明/配置了注释。
以下是它的工作原理: ReSharper NullReferenceException分析及其合约
不幸的是,有时候,这些有用的注释是错误的。
当您检测到错误时,应将其报告给JetBrains,他们将更新下一版本的注释。 他们习惯了这个。
同时,您可以尝试自己修复它。 阅读文章了解更多:)
如果在给定代码上方检查,请检查您是否有任何用户== null。 如果有,那么ReSharper认为变量“可以为null”,因此建议您在引用它之前使用check / assert。 在某些情况下,这是ReSharper可以猜测变量是否可以为空的唯一方法。