Den*_*Den 4 resharper null design-by-contract static-analysis
看来,NotNull和ContractAnnotation("key: null => halt")在其上的R·效果相当类似.有什么东西我错过了吗?我应该经常同时申请吗?
cit*_*att 10
它们非常相似,但在语义上非常不同.
NotNull声明目标预计不会为空,但不会对结果做出任何陈述.可能存在抛出一个null检查ArgumentNullException,或者它可能只是在没有检查的情况下使用它,并且您可以获得运行时NullReferenceException.同样,应用程序可能会检查null,记录并安全继续.
ContractAnnotation("key: null => halt")告诉ReSharper,如果key参数为null,则程序流程终止.ReSharper可以这样使用:
string foo = null;
Assert.NotNull(foo); // ContractAnnotation("null => halt")
Assert.Equal(12, foo.length);
Run Code Online (Sandbox Code Playgroud)
此片段中的第二个断言将被标记为死代码,因为ReSharper知道第一个断言将在传递null时抛出.
但是,如果Assert.NotNull只是用NotNull属性标记,那么ReSharper会突出显示foo带有警告的参数,告诉您不应该传递空值,但是如果这样做,它不知道会发生什么.
微妙但不同.NotNull如果你要求值永远不为null,我会坚持使用该属性,并使用ContractAnnotation("null => halt")断言样式方法,如果传递null,它将明确地和显式地抛出.
简而言之:
通常你应该只使用[NotNull]/ [CanBeNull]注释.如果您违反合同,R#将验证它们是否通知.它们通过接口实现和虚拟方法覆盖进行传播.它们很容易理解.
[ContractAnnotation]如果您需要在指定方法行为方面更具表现力,则可以使用.它不是[NotNull]/ 的替代品[CanBeNull].它允许您链接方法输入和输出,链接notnull/ null/ true/ false值,指定将使您成为方法的输入halt.您传递给的字符串[ContractAnnotation]称为"函数定义表",这只是方法体行为的抽象.
通常需要在以下情况下使用[ContractAnnotation]何时[NotNull]/ [CanBeNull]表达不足:
if (!IsNotNullAndAlsoValid(obj)) return; // null => false
Assert.That(x != null); // false => halt
if (!map.TryGetValue(key, out value)) { // => false, value: null
... // + key parameter annotated as [NotNull]
}
Run Code Online (Sandbox Code Playgroud)
是的,[NotNull]在语义上与...不同[ContractAnnotation("null => halt")].这很容易在代码中说明,有时R#肯定会因为NRE而暂停执行,并将剩余的代码强调为"死":
C c = null;
c.InstanceMethod(); // possible NRE
c.SomethingElse(); // unreachable code
Run Code Online (Sandbox Code Playgroud)
但是当你使用[NotNull]-annotated API时,R#只会警告你'可能的NRE'.这样做是因为在R#没有足够的关于某些值不为空的信息的情况下,它不应该突出显示其他方法可能无法访问:
C c = AlwaysTrue ? new C() : null;
Util.NotNullAnnotatedMethod(c); // possible NRE
Util.OtherMethod(c); // no warnings here
if (c != null) { ... } // no warnings here
Run Code Online (Sandbox Code Playgroud)
虽然[ContractAnnotation]允许您更严格地指定行为,但R#将更积极地依赖注释:
if (string.IsNullOrEmpty(text)) return; // text: null => false
if (text != null) { ... } // condition always true
else { ... } // unreachable code
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1508 次 |
| 最近记录: |