【问题标题】:ReSharper: how to remove "Possible 'System.NullReferenceException'" warningReSharper:如何删除“可能的'System.NullReferenceException'”警告
【发布时间】:2011-05-22 13:30:33
【问题描述】:

这是一段代码:

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' 对象的第一次使用。

第一季度。为什么会产生这样的异常?据我所知,如果user==null 则将生成异常并且执行将永远不会到达使用点。

第二季度。如何删除该警告?请注意: 1.我不想用cmets压制这个警告(我会有很多类似的部分,不想把我的源代码转换成'注释垃圾'); 2. 我不想更改 ReSharper 设置以将此问题从警告更改为“提示”的“建议”。

谢谢。

欢迎提出任何想法!

附:我正在使用 resharper 5.1、MVSV 2008、C#

【问题讨论】:

    标签: c# .net configuration resharper nullreferenceexception


    【解决方案1】:

    Resharper 只查看当前方法进行分析,不会递归分析你调用的其他方法。

    但是,您可以稍微指导 Resharper 并为其提供有关某些方法的元信息。例如,它知道“Assert.IsNotNull(a)”,并将在分析时考虑该信息。可以为 Resharper 制作一个外部注释文件,并为其提供有关某个库的额外信息,以使其分析更好。也许这可能会提供解决您问题的方法。

    更多信息可以在here找到。

    可以在here 找到一个展示它如何用于 Microsoft.Contracts 库的示例。

    【讨论】:

      【解决方案2】:

      旧帖子中的新答案...

      这里有一个关于如何通过 ContractAnnotation 和 Resharper 使用 CodeContract 的代码示例:

          [ContractAnnotation("value:null=>true")]
          public static bool IsNullOrEmpty(this string value)
          {
              return string.IsNullOrEmpty(value);
          }
      

      这很简单……如果你在木头里找到面包屑。您也可以检查其他情况。

      祝你有美好的一天

      【讨论】:

      • 如果你知道某个方法总是抛出异常,你可以这样做[ContractAnnotation("=&gt; halt")]
      【解决方案3】:

      Q1:因为 Resharper 不做路径分析。它只是看到一个可能的 null 引用并标记它。

      Q2:你不能不做你已经提供的任何一个。

      【讨论】:

        【解决方案4】:

        您确实知道(或期望)如果存在空引用,此代码将引发异常:

        ComponentException<MyUserManagerException>.FailIfTrue([...]);
        

        但是,由于没有合同规定这一点,ReSharper 必须假设这只是一个正常的方法调用,在任何情况下都可能返回而不会引发任何异常。

        FailIfTrue 调用之后,使此方法实现 ReSharper 合约,或作为一种简单的解决方法(仅影响调试模式,因此不会影响发布模式的性能):

        Debug.Assert(user != null);
        

        这将消除警告,并且作为额外的好处,在调试模式下进行运行时检查,以确保您在调用 FailIfTrue 后假设的条件确实得到满足。

        【讨论】:

        • 我希望这是真的...... Resharper 5.1 无法正确识别 Debug.Assert(user != null); 并发出警告。有什么需要我做的配置吗?
        • 呃,R# 5.1 已经过时了,所以我没有什么可以测试你的问题。然而,一些提示:确保您的代码正确引用 System.Diagnostics.Debug 类,因为代码协定是为此定义的,而不是具有该名称/签名的任意方法。另外,确保构建配置设置为调试(否则代码超出范围,因此会弹出警告!)。
        【解决方案5】:

        这是由 Resharper 引擎引起的。这些“可能的 NullReferenceException”发生是因为有人(可能在 Resharper)在某处声明/配置了该方法的注释。

        这是它的工作原理:ReSharper NullReferenceException Analysis and Its Contracts

        很遗憾,有时这些有用的注释是错误的。

        当您检测到错误时,应将其报告给 JetBrains,他们将在下一个版本中更新注释。他们已经习惯了。

        同时,您可以尝试自己修复它。阅读文章了解更多信息:)

        【讨论】:

          【解决方案6】:

          如果在给定代码上方检查,请检查您是否有任何 user==null。如果存在,则 ReSharper 认为变量“可以为空”,因此建议您在引用它之前使用检查/断言。在某些情况下,这是 ReSharper 猜测变量是否可以为 null 的唯一方法。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2014-06-17
            • 1970-01-01
            • 2021-08-27
            • 1970-01-01
            • 1970-01-01
            • 2019-08-04
            • 1970-01-01
            相关资源
            最近更新 更多