Ste*_*e B 10 code-contracts c#-4.0
我正在使用代码合同(实际上,使用这个来学习).
我面临一些奇怪的事情......我重写了一个在第三方程序集中定义的方法.我想添加一个Contract.Require这样的语句:
public class MyClass: MyParentClass
{
protected override void DoIt(MyParameter param)
{
Contract.Requires<ArgumentNullException>(param != null);
this.ExecuteMyTask(param.Something);
}
protected void ExecuteMyTask(MyParameter param)
{
Contract.Requires<ArgumentNullException>(param != null);
/* body of the method */
}
}
Run Code Online (Sandbox Code Playgroud)
但是,我收到这样的警告:
警告1 CodeContracts:方法'MyClass.DoIt(MyParameter)'覆盖'MyParentClass.DoIt(MyParameter))',因此无法添加Requires.
[编辑]稍微更改了代码以显示替代问题[/ edit]
如果我删除了Contract.RequiresDoIt方法,我会收到另一个警告,告诉我必须提供未经证实的param != null
我不明白这个警告.原因是什么,我可以解决吗?
Jon*_*eet 14
您无法添加呼叫者可能不知道的额外要求.它违反了Liskov的Subtitution Principle.多态性的一点是,调用者应该能够处理实际引用派生类实例的引用,就好像它引用了基类的实例一样.
考虑:
MyParentClass foo = GetParentClassFromSomewhere();
DoIt(null);
Run Code Online (Sandbox Code Playgroud)
如果那是静态地确定是有效的,那么你的派生类举起手来说"不!你不打算DoIt用空参数调用!"是错误的.合同的静态分析的目的是你可以在编译时确定调用,逻辑等的有效性......因此在执行时不能添加额外的限制,这是由于多态性在这里发生的.
派生类可以增加对它将要做什么的保证 - 它将确保什么 - 但它不能使其调用者对重写方法提出任何更多要求.