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);
答案 0 :(得分:11)
是的。您需要使用ReSharper annotations来指导ReSharper的分析。您已经在使用[CanBeNull]
,因此已经在项目中定义了它们。
您感兴趣的是ContractAnnotationAttribute
:
契约注释允许您定义给定输入的预期输出,换句话说,定义函数的引用类型和布尔参数之间的依赖关系及其返回值。契约注释机制允许创建可以更容易和更安全的方式使用的API。
这是您使用它的方式:
[ContractAnnotation("null => false")]
public static bool IsNotNullOrEmpty(this string value)
=> !string.IsNullOrEmpty(value);
参数是可能输入的映射(null
,notnull
,true
,false
)到输出(null
,notnull
,canbenull
,true
,false
,halt
):
这是另一个例子:
[ContractAnnotation("foo: null => halt; bar: notnull => notnull")]
public string Frob(string foo, string bar)
表示如果将null
传递给foo
参数,装饰函数将永远不会返回(或抛出异常),并保证它不会返回null
如果您将非空值传递给bar
。
The documentation更详细地描述了语法。
这里没有属性会发生什么:
添加后警告消失: