我可以教 ReSharper 自定义 null 检查吗?

Can I teach ReSharper a custom null check?

ReSharper 足够聪明,知道 string.Format 需要一个非空 format 参数,所以当我简单地写

时它会警告我
_message = string.Format(messageFormat, args);

其中 messageFormat 确实可以为空。只要我为此变量添加条件:

if (!string.IsNullOrEmpty(messageFormat))
{
    _message = string.Format(messageFormat, args);
}

警告消失。不幸的是,当我使用扩展方法时它没有:

if (messageFormat.IsNotNullOrEmpty())
{
    _message = string.Format(messageFormat, args); // possible 'null' assignment warning
}

我的问题是:有没有办法 教导 ReSharper 我的扩展方法与 !string.IsNullOrEmpty(messageFormat) 具有相同的含义?

扩展定义为:

public static bool IsNotNullOrEmpty([CanBeNull] this string value) => !IsNullOrEmpty(value);

是的。您需要使用 ReSharper annotations 来指导 ReSharper 的分析。您已经在使用 [CanBeNull],因此它们已在您的项目中定义。

您感兴趣的是 ContractAnnotationAttribute:

Contract annotations let you define expected outputs for given inputs, or put in other words, define dependencies between reference type and boolean arguments of a function and its return value. The mechanism of contract annotations allows creating APIs that could be consumed in easier and safer way.

你是这样使用它的:

[ContractAnnotation("null => false")]
public static bool IsNotNullOrEmpty(this string value)
    => !string.IsNullOrEmpty(value);

参数是可能的输入(nullnotnulltruefalse)到输出(nullnotnull, canbenull, true, false, halt):

这是另一个例子:

[ContractAnnotation("foo: null => halt; bar: notnull => notnull")]
public string Frob(string foo, string bar)

意味着装饰函数永远不会 return (或抛出异常)如果你将它 null 传递给 foo 参数,并保证它不会 return null 如果将非空值传递给 bar.

The documentation 更详细地描述了语法。


如果没有该属性,会发生以下情况:

添加后警告消失: