如何向r#指示函数检查变量是否为空

本文关键字:变量 是否 检查 函数 指示 | 更新日期: 2023-09-27 17:49:42

在我们的代码库中,我们有一组自定义错误检查函数(就像这里列出的那些函数)来检查参数,而不是冗长的检查。例如,要检查一个参数是否为空,我使用:

Throw.IfNull(theArgument, "theArgument");

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

如何向r#指示函数检查变量是否为空

你问的问题绝对可以通过应用ReSharper annotation来解决!这些属性为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属性来装饰它,ContractAnnotation, NotNullInvokerParameterName,像这样:

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

这些属性的作用如下:

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

第二个是[NotNull],告诉ReSharper parameter不能为启发式null。这给出了"可能为null赋值给带有[NotNull]属性的实体"的警告。

第三,[InvokerParameterName]告诉ReSharper parameterName参数是调用(调用)方法的一个参数的名称,所以它将提供代码补全,列出所有调用方法的参数。这将在ReSharper中给出一个警告,如果名字不是一个参数,例如,一个局部变量的名字。

下面是这些属性的简短视频(应用于另一组api,但思想是完全相同的):http://screencast.com/t/NhGVaUr7GO3b