在继承链中重复代码协定要求
本文关键字:代码 继承 | 更新日期: 2023-09-27 18:34:56
假设你有一个现有的大型项目,你想在其中集成代码协定。现有代码使用 if-null-then-throw 逻辑。对于给定的条件,文档建议将程序集模式设置为自定义参数验证。
我有以下课程:
class A
{
protected virtual void Foo(int a, int b)
{
if (a == null)
throw new ArgumentNullException(a);
if (b == null)
throw new ArgumentNullException(b);
Contract.EndContractBlock();
}
}
class B : A
{
protected override void Foo (int a, int b)
{
// some stuff
base.Foo(a, b);
}
}
当我编译时,我收到以下警告:
警告 CC1055:方法"B.Foo(int, int("应包含自定义 'Requires(a != null(' 的参数验证 因为它覆盖了"A.Foo(int,int(",这表明它确实如此。如果你不这样做 想要在此程序集中使用自定义参数验证,请将 组装模式为"标准协定要求"。
我不想在每个被覆盖的方法上重复前提条件!有没有办法解决它?
如果您使用 Contract.Requires()
而不是 Contract.EndContractBlock()
,它可以正常工作。
下面引用的手册中有一节建议将[SuppressMessage]
属性添加到方法重写中。
摘自代码契约用户手册第 22 页第 5.2.3 节。
将检查委派给其他方法
假设您有一个类似于以下代码的代码模式:
public class Base { public virtual void Compute(string data) { if (data == null) throw new ArgumentNullException(...); Contract.EndContractBlock(); ... } } public class Derived : Base { public override void Compute(string data) { base.Compute(data); ... } }
然后,这些工具将发出警告 CC1055,并显示以下形式的消息:
方法"派生.计算"应包含自定义参数验证 ' 需要 (ArgumentNullException((data ! = null(' 因为它覆盖 "Base.Compute"表明它确实如此。
在这种情况下,警告没有帮助,因为实现 的派生。计算将参数验证委托给另一个 方法(在本例中为基方法(。为了避免此处的警告 在不重复验证的情况下,您可以添加一个 抑制消息 方法的属性:
public class Derived : Base { [SuppressMessage("Microsoft.Contracts", "CC1055", Justification = "Validation performed in base method")] public override void Compute(string data) { base.Compute(data); ... } }