【问题标题】:How to indicate to R# that a function checks a variable for null如何向 R# 指示函数检查变量是否为空
【发布时间】:2014-03-12 18:41:28
【问题描述】:

在我们的代码库中,我们有一系列自定义错误检查函数(如here 列出的那些),以减少检查参数的冗长。例如,要检查 null 我使用的参数:

Throw.IfNull(theArgument, "theArgument");

这种方法的一个缺点是 R# 会在该值的未来使用中给出警告“可能的 NullReferenceException”,因为它不够聪明,无法将其检测为空检查(或者至少在 theArgument 为空时会失败) )。有什么方法可以表明此方法检查参数是否为空?例如,当我尝试在这样的值上运行像 Select() 这样的静态扩展时,R# 会警告我“可能对标有 NotNull 属性的实体进行空分配”,但我找不到此类属性的任何文档,也找不到我在 Enumerable.Select() 的参考源中看到了吗?

【问题讨论】:

    标签: c# visual-studio-2012 resharper


    【解决方案1】:

    申请ReSharper Annotations绝对可以解决您的问题!这些属性为 ReSharper 的分析提供了额外的提示,允许您将 ReSharper 的“优点”添加到您自己的方法和类中。我最近与 JetBrains 录制了一个名为 ReSharper Secrets 的网络研讨会,我在其中讨论和演示注释,欢迎您观看!

    至于您的问题,您可以应用 3 个注释属性来解决您的问题(并添加更多很酷的功能)。

    假设IfNull 的定义类似于:

    public static class Throw
    {
        public static void IfNull<T>(T parameter, string parameterName) where T : class
        {
            if (parameter == null) 
                throw ArgumentNullException(string.Format("Parameter {0} is null", parameterName));
        }
    }
    

    您可以使用 3 个 ReSharper 属性来装饰它,ContractAnnotationNotNullInvokerParameterName,如下所示:

    [ContractAnnotation("parameter: null => halt")]
    public static void IfNull<T>([NotNull] T parameter,
                                 [InvokerParameterName] string parameterName) 
        where T : class
    {
        ...
    }
    

    这些属性的作用如下:

    第一个 [ContractAnnotation] 告诉 ReSharper,如果 parameter 启发式地为 null,则此方法会停止程序执行,即抛出异常(在运行时)。这就是防止“可能的 NullReferenceException”警告的原因。用于定义合约注解的语言在here 进行了解释。

    第二个是 [NotNull],告诉 ReSharper parameter 不能试探性地为空。这会给出“可能对标有 [NotNull] 属性的实体进行空分配”警告。

    第三个,[InvokerParameterName] 告诉 ReSharper parameterName 参数是来自调用(调用)方法的参数之一的名称,因此它将提供列出所有调用方法参数的代码完成。如果名称不是参数(例如,局部变量名称),这将在 ReSharper 中发出警告。

    以下是这些属性的实际操作短视频(应用于另一组 API,但思路完全相同):http://screencast.com/t/NhGVaUr7GO3b

    【讨论】:

      猜你喜欢
      • 2011-12-19
      • 1970-01-01
      • 1970-01-01
      • 2011-05-20
      • 1970-01-01
      • 2012-02-05
      相关资源
      最近更新 更多