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