JetBrains Rider 2025.2 Help

契约注解

契约注解允许您为给定的输入定义预期的输出,或者换句话说,定义函数的引用类型和布尔参数与其返回值之间的依赖关系。 契约注解机制允许创建更易于使用且更安全的 API。

您可以通过使用 [ContractAnnotationAttribute] 装饰您的函数来实现契约注解。 如果您想在源代码中实现此功能,请 引用 JetBrains.Annotations 命名空间。 您还可以使用 外部注解 为现有的二进制模块中的函数添加注解。

运作方式

为了快速了解如何以及为什么使用契约注解,请查看下面的示例。

在此示例中,我们使用契约注解属性装饰了函数 调整。 在这种情况下,属性参数的含义是,null 参数总是会产生 null 返回值。 您可以轻松阅读此示例的代码以了解函数是如何工作的,但在实际代码中,这种依赖关系可能并不那么明显。 无论如何,这里的重点是描述函数如何处理输入值的契约注解属性。

当我们使用 'null' 参数调用 调整 函数时,JetBrains Rider 会立即发现并突出显示一系列问题。 首先,它会突出显示带有 null 参数的函数调用,警告此表达式始终为 null。 然后,它会继续跟踪用此表达式初始化的 已调整 变量,现在该变量也为 'null'。 当我们检查 已调整 变量是否不等于 'null' 时,JetBrains Rider 再次警告我们此比较始终为 false。 最后,JetBrains Rider 将 'if' 语句中的代码标记为不可达代码并变灰:

基于契约注解的 JetBrains Rider 代码检查

合同注解的语法

使用以下语法指定合同注解的输入输出依赖关系:

[ContractAnnotation("[paramName:][input] => output [; [paramName:][input] => output]", [forceFullStates:true])]

输入 可以是:

  • null/非空 用于引用类型参数

  • true/false 用于布尔类型参数。

输出 可以是

  • null/非空/canbenull 用于引用类型的返回值

  • true/false 用于布尔类型的返回值

  • 中止 | 停止 | void | 无任何内容 (它们是可互换的)以指示函数不会正常返回。 也就是说,它会抛出异常或停止程序执行。

可选的布尔 forceFullStates 参数,默认为 false,允许您为可空性分析强制启用 悲观模式。 也就是说,如果方法的返回值未由合同条件定义,JetBrains Rider 将假定它可能为 null。

备注:

  • 如果只有一个参数,您可以省略 paramName (请参见上面的示例)

  • 如果没有参数,您可以同时省略 paramName输入

    [ContractAnnotation("=> halt")] public void TerminationMethod()

    或者如果函数的输出与输入无关:

    [ContractAnnotation("=> halt")] public void TerminationMethod(object data, bool flag)
  • 您可以为同一参数添加多个条件:

    [ContractAnnotation("input:null => null; input:notnull=>notnull")] public object Transform(object input, bool flag)
  • 您可以反转条件,也就是说 input => output 等于 output <= input

    [ContractAnnotation("null <= surname:null")] public string GetName(string surname)
  • 您还可以为 'out' 参数指定预期值。 如果您想为同一输入条件同时指定返回值和 'out' 参数,请使用逗号:

    [ContractAnnotation("s:null => false,result:null")] public bool TryParse(string s, out object result)

契约条件的验证

如果您在 源代码中使用契约注解装饰函数,JetBrains Rider 会根据函数签名验证契约条件。 如果契约注解不适合函数参数,JetBrains Rider 会显示警告:

JetBrains Rider:契约注解

如果契约注解不适合返回值,也会发生同样的情况。

JetBrains Rider:契约注解
最后修改日期: 2025年 9月 26日