C# CodeContracts错误地标记缺少已存在于基本构造函数中的前提条件
假设我有以下类层次结构:C# CodeContracts错误地标记缺少已存在于基本构造函数中的前提条件,c#,code-contracts,constructor-chaining,C#,Code Contracts,Constructor Chaining,假设我有以下类层次结构: public class FooBase { private readonly object _obj; protected FooBase(object obj) { Contract.Requires(obj != null); _obj = obj; } } public class Foo : FooBase { public Foo(object obj) : base(obj)
public class FooBase
{
private readonly object _obj;
protected FooBase(object obj)
{
Contract.Requires(obj != null);
_obj = obj;
}
}
public class Foo : FooBase
{
public Foo(object obj) : base(obj)
{
}
}
编译时,我得到Foo
的以下CodeContracts错误:
Error 12 CodeContracts: Missing precondition in an externally visible method. Consider adding Contract.Requires(obj != null); for parameter validation
有没有办法让CodeContracts认识到验证已经在基类中发生了?不幸的是,没有。
您的Foo调用FooBase(obj)时没有适当的要求
public class FooBase
{
private readonly object _obj;
protected FooBase(object obj)
{
Contract.Requires(obj != null);
_obj = obj;
}
}
public class Foo : FooBase
{
public Foo(object obj) : base(obj)
{
Contract.Requires(obj != null);
}
}
将是解决此问题的唯一方法。不过我认为信息是准确的;你看不到基本类,只有子类,子类没有契约。我怀疑如果您从子类上的公共方法调用基方法,情况也会一样。方法不会“继承”契约。如果
FooBase
有一个无参数的构造函数,那么您就有理由这样做。但是如果没有,则基本构造函数契约不可能不被调用。因此,我回到我最初的问题…但这不是合同的工作方式。分析器只是孤立地看待这个方法,在确定前置和后置条件时,它没有考虑它调用的其他方法。这很公平——我把你的论点放在常规方法上。但也许作者应该考虑改变这一点,以考虑构造函数链接。在我看来,这是一种特殊情况。我不想无意识地重复不必要的代码,只是为了让静态检查器满意。那么,ctor和普通方法(除了调用它们的规则)之间的区别是什么呢?为什么他们不为其他方法也这样做呢?我认为你的建议在合同设计中不可行;子类型实际上被允许削弱前置条件,如果您从调用的任何方法继承了这些条件,这是不可能的。ctor还应该能够削弱先决条件。