为什么不能在重写方法中添加Contract.Requires? [英] Why can't I add Contract.Requires in an overridden method?
问题描述
我正在使用代码协定(实际上是在学习使用它)。
I'm using code contract (actually, learning using this).
我正面临着一些奇怪的事情……我覆盖了一种方法,该方法定义于第三党集会。我想添加一个 Contract.Require
语句,像这样:
I'm facing something weird to me... I override a method, defined in a 3rd party assembly. I want to add a Contract.Require
statement like this:
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 */
}
}
但是,我收到这样的警告:
However, I'm getting warnings like this:
警告1代码合同:
方法'MyClass.DoIt(MyParameter)'覆盖'MyParentClass.DoIt(MyParameter)),因此无法添加Requires。
Warning 1 CodeContracts: Method 'MyClass.DoIt(MyParameter)' overrides 'MyParentClass.DoIt(MyParameter))', thus cannot add Requires.
[edit] 已更改该代码有点显示替代问题 [/ edit]
[edit] changed the code a bit to show alternatives issues [/edit]
如果我删除了 Contract.Requires
在DoIt方法中,我收到另一个警告,告诉我必须提供未经证实的 param!= null
我不理解此警告。是什么原因,我可以解决吗?
If I remove the Contract.Requires
in the DoIt method, I get another warning, telling me I have to provide unproven param != null
I don't understand this warning. What is the cause, and can I solve it?
推荐答案
您不能添加呼叫者可能不知道的额外要求。它违反了 Liskov的替代原则。多态的意义在于,调用方应该能够将实际上引用了您的派生类的实例的引用当作引用它引用基类的实例。
You can't add extra requirements which your callers may not know about. It violates Liskov's Subtitution Principle. The point of polymorphism is that a caller should be able to treat a reference which actually refers to an instance of your derived class as if it refers to an instance of the base class.
考虑:
MyParentClass foo = GetParentClassFromSomewhere();
DoIt(null);
如果从静态上确定这是有效的,那么派生类举起双手说错了不!您不应该使用空参数来调用 DoIt
!合同静态分析的目的是,您可以在编译时确定调用,逻辑等的有效性...因此在执行时不能添加任何额外的限制,这是由于多态性导致的。
If that's statically determined to be valid, it's wrong for your derived class to hold up its hands and say "No! You're not meant to call DoIt
with a null argument!" The aim of static analysis of contracts is that you can determine validity of calls, logic etc at compile-time... so no extra restrictions can be added at execution time, which is what happens here due to polymorphism.
派生类可以为其执行的操作(将确保的操作)添加保证,但不能从其调用方发出对覆盖方法的更多要求。
A derived class can add guarantees about what it will do - what it will ensure - but it can't make any more demands from its callers for overridden methods.
这篇关于为什么不能在重写方法中添加Contract.Requires?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!