当已经检查null时,ReSharper可能为Null Exception

时间:2012-08-19 12:55:49

标签: c# resharper extension-methods nullreferenceexception code-contracts

这是使用Visual Studio 2012的ReSharper 7.使用下面的示例

// This code works fine and as expected and ReShrper is happy with it
if (!string.IsNullOrWhiteSpace(extension) && extension.Length == 3)
{
    // do something
}

// ReSharper highlights "extension" in extension.Length with "Possible 'System.NullReferenceException'"
if (!extension.IsNullOrWhiteSpace() && extension.Length == 3)
{
    // do something
}

并且,我创建了以下扩展方法:

public static class StringExtensions
{
    public static bool IsNullOrWhiteSpace(this string s)
    {
        return string.IsNullOrWhiteSpace(s);
    }
}

我查看了String.IsNullOrWhiteSpace的反映代码,但它没有任何相关的代码或属性会突出显示R#验证检查。这是硬编码的R#?

我查看了代码合同,但我不确定它会对我的情况有所帮助。

您是否有一种解决方法可以向ReSharper证明我的扩展方法已经验证了检查条件?

3 个答案:

答案 0 :(得分:15)

在Resharper 7及以上版本

中可用
[ContractAnnotation("null=>true")]
public static bool IsNullOrWhiteSpace(this string s)

您的项目不知道ContractAnnotation是什么。您需要将它添加到您的项目中。首选方法是通过nuget:

  

PM>安装包JetBrains.Annotations

或者,您可以直接将源代码嵌入到项目中:

  

Resharper - >选项 - >代码注释 - >将默认实现复制到剪贴板

然后将其粘贴到新文件中,例如Annotations.cs。 ContractAnnotation定义存在于该文件中。有关ContractAnnotation的官方文章,请参阅here


以前的答案(非R#7版本)

  

这是在R#中硬编码吗?

不,Resharper使用External Annotations提供此功能。 This article应该回答您的所有问题,包括为您的IsNullOrWhiteSpace方法提供自己的外部注释的解决方案。

实施例

注意:外部注释似乎只适用于引用的库;如果您的参考来自项目,则不会选择外部注释;这不太理想

假设您在名为TempExtensions的类中有扩展方法,该类本身位于名为ClassLibrary1

的程序集中

您需要在此位置添加新文件

  

C:\ Program Files(x86)\ JetBrains \ ReSharper \ v7.0 \ Bin \ ExternalAnnotations.NETFramework.ExternalAnnotations \ ClassLibrary1 \ ClassLibrary1.xml

xml的内容应包含:

<assembly name="ClassLibrary1">
  <member name="M:ClassLibrary1.TempExtensions.IsNullOrWhiteSpace(System.String)">
    <attribute ctor="M:JetBrains.Annotations.ContractAnnotationAttribute.#ctor(System.String,System.Boolean)">
        <argument>null=&gt;true</argument>
        <argument>true</argument>
    </attribute>
  </member>
</assembly>

答案 1 :(得分:0)

据我所知,这是resharper的一个问题。它无法查看方法并验证在方法中将进行null检查。如果你想避免这个消息,我想你必须自己进行空值检查。但我宁愿在这种情况下忽略resharper消息。

答案 2 :(得分:0)

我看到的唯一解决方法是将函数参数添加到扩展方法。

public static class StringExtensions
{
  public static bool IsNotNullAndNotWhiteSpaceAnd(this string s, Func<string, bool> func)
  {
    if (string.IsNullOrWhiteSpace(s))
    {
      return false;
    }

    return func(s);
  }
}

使用此扩展方法的示例:

string extension = null;     //Test for null
//string extension = "123";  //Test for Length==3


if (extension.IsNotNullAndNotWhiteSpaceAnd(_ => _.Length == 3))
{
  Console.Out.WriteLine("Length == 3");
}
else
{
  Console.Out.WriteLine("Null or WhiteSpace or Length != 3");
}