首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我应该同时使用NotNull和ContractAnnotation("null => halt")吗?

我应该同时使用NotNull和ContractAnnotation("null => halt")吗?
EN

Stack Overflow用户
提问于 2014-06-01 21:16:40
回答 2查看 2.2K关注 0票数 4

NotNullContractAnnotation("key: null => halt")对R#的影响似乎是相当相似的。我遗漏了什么吗?我应该同时应用两者吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-06-02 08:56:36

它们非常相似,但在语义上非常不同。

NotNull指出,预期目标不会为null,但不会声明结果。可能有一个空检查抛出一个ArgumentNullException,或者它可能只是在不检查的情况下使用它,您可以得到一个运行时NullReferenceException。同样,应用程序可能会检查null,记录它并安全地继续。

ContractAnnotation("key: null => halt")告诉ReSharper,如果key参数为null,那么程序流将终止。ReSharper可以这样使用:

代码语言:javascript
复制
string foo = null;
Assert.NotNull(foo);  // ContractAnnotation("null => halt")
Assert.Equal(12, foo.length);

这个片段中的第二个断言将被标记为死代码,因为ReSharper知道第一个断言在被传递为null时会抛出。

但是,如果Assert.NotNull只是被标记为NotNull属性,那么ReSharper将用警告突出显示foo参数,告诉您不应该传递空值,但是它不知道如果这样做会发生什么。

很微妙,但不一样。如果您要求值永不为空,我将坚持使用NotNull属性,并将ContractAnnotation("null => halt")用于断言样式方法,如果传递null,该方法将明确和显式抛出。

票数 10
EN

Stack Overflow用户

发布于 2014-06-02 13:36:54

简言之:

  • 通常,您应该只使用[NotNull]/[CanBeNull]注释。它们由R#验证,以通知您是否正在违反合同。它们通过接口实现和虚拟方法重写传播。它们很容易理解。
  • 如果需要更有表现力地指定方法的行为方式,可以使用[ContractAnnotation]。它不是[NotNull]/[CanBeNull]的替代品。它允许您链接方法输入和输出、链接notnull/null/true/false值、指定将使您的方法为halt的输入。您要传递给[ContractAnnotation]的字符串称为“函数定义表”,这只是对方法主体行为的抽象。

在以下情况下,当[ContractAnnotation] / [NotNull]/[CanBeNull]没有足够的表达能力时,通常需要使用[CanBeNull]

代码语言:javascript
复制
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]
}

是的,[NotNull]在语义上不同于[ContractAnnotation("null => halt")]。这很容易在代码中得到说明,有时R#肯定知道执行会因为NRE而停止,并将剩余的代码突出显示为“死”:

代码语言:javascript
复制
C c = null;
c.InstanceMethod(); // possible NRE
c.SomethingElse();  // unreachable code

但是当您使用[NotNull]-annotated API时,R#只是提醒您注意“可能的NRE”。这是因为在这种情况下,R#没有足够的信息说明某些值为null,因此不应该将其余的方法突出显示为潜在不可访问的:

代码语言:javascript
复制
C c = AlwaysTrue ? new C() : null;
Util.NotNullAnnotatedMethod(c); // possible NRE
Util.OtherMethod(c);            // no warnings here
if (c != null) { ... }          // no warnings here

虽然[ContractAnnotation]允许您更严格地指定行为,因此R#将更积极地依赖注释:

代码语言:javascript
复制
if (string.IsNullOrEmpty(text)) return; // text: null => false
if (text != null) { ... }               // condition always true
else { ... }                            // unreachable code
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23984569

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档