【问题标题】:How does ReSharper know "Expression is always true"?ReSharper 如何知道“表达式总是正确的”?
【发布时间】:2011-07-01 08:51:25
【问题描述】:

查看以下代码:

private void Foo(object bar)
{
   Type type = bar.GetType();

    if (type != null) // Expression is always true
    {   
    }
}

ReSharper 声称 type 永远不会是 null。这对我来说很明显,因为bar 总是有一个类型,但是 ReSharper 是怎么知道的呢?它怎么知道方法的结果永远不会是null

Type 不是结构,所以不可能是这样。而且如果方法是我写的,那么返回值肯定是null(不一定是GetType,而是别的)。

ReSharper 是否足够聪明地知道,仅对于该特定方法,结果永远不会是 null? (就像有一个硬编码的已知 .NET 方法列表,它们永远不会返回 null。)

【问题讨论】:

    标签: c# resharper


    【解决方案1】:

    JetBrains 在他们的 features list 中完美地解释了 ReSharper 如何做到这一点。

    链接摘要(这个问题是关于NotNullAttribute):

    我们分析了很大一部分 .NET Framework 类库以及 NUnit Framework,并使用 JetBrains.Annotations 命名空间中的一组自定义属性通过外部 XML 文件对其进行了注释,具体来说:

    StringFormatMethodAttribute (for methods that take format strings as parameters)
    InvokerParameterNameAttribute (for methods with string literal arguments that should match one of caller parameters)
    AssertionMethodAttribute (for assertion methods)
    AssertionConditionAttribute (for condition parameters of assertion methods)
    TerminatesProgramAttribute (for methods that terminate control flow)
    CanBeNullAttribute (for values that can be null)
    NotNullAttribute (for values that can not be null)
    UsedImplicitlyAttribute (for entities that should not be marked as unused)
    MeansImplicitUseAttribute (for extending semantics of any other attribute to mean that the corresponding entity should not be marked as unused)
    

    【讨论】:

    • 如果您在答案中也提供了原因的简短摘要,将会很有帮助。
    【解决方案2】:

    是的,它基本上掌握了一些众所周知的方法。您也应该找到相同的字符串连接,例如:

    string x = null;
    string y = null;
    string z = x + y;
    
    if (z == null)
    {
        // ReSharper should warn about this never executing
    }
    

    现在可以通过代码合同获得相同的信息 - 我不知道 JetBrains 是直接连接到这些信息中,有自己的数据库,还是两者的混合。 p>

    【讨论】:

    • 很高兴有人提到代码合同。
    • @Sapph:真可惜。也许它真的知道字符串连接:(
    • @JonSkeet 至少从 ReSharper 版本 2018.2.3 开始,它确实会使用您的确切代码 sn-p 发出此警告。
    【解决方案3】:

    GetType 不是virtual。您的假设在您最后的陈述中很可能是正确的。

    编辑:回答您的评论问题 - 它无法用您的方法推断出开箱即用。

    【讨论】:

    • 对不起,我的问题没有很好地解释。我的意思是说,如果我实现了一些其他方法,与 Resharper 无法推断结果永远不会为 null 的 GetType() 无关
    【解决方案4】:

    object.GetType 不是虚拟的,因此您不能自己实现返回空值的版本。因此,如果bar 为空,您将获得NullReferenceException,否则,type 将永远不会为空。

    【讨论】:

    • 对不起,我的问题没有很好地解释。我的意思是说,如果我实现了一些其他方法,与 GetType() 无关,Resharper 无法推断结果永远不会为空。
    • @RichK,你是对的。 Resharper 无法推断出这一点。
    猜你喜欢
    • 2018-07-24
    • 1970-01-01
    • 2011-07-30
    • 1970-01-01
    • 1970-01-01
    • 2023-03-03
    • 1970-01-01
    • 1970-01-01
    • 2019-07-15
    相关资源
    最近更新 更多