Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么可以为后置条件和对象不变量添加和删除代码契约,而不能为C#中的前置条件添加和删除代码契约?_C#_Code Contracts - Fatal编程技术网

为什么可以为后置条件和对象不变量添加和删除代码契约,而不能为C#中的前置条件添加和删除代码契约?

为什么可以为后置条件和对象不变量添加和删除代码契约,而不能为C#中的前置条件添加和删除代码契约?,c#,code-contracts,C#,Code Contracts,为什么可以为后置条件和对象不变量添加和删除代码契约,而不能为C#中的前置条件添加和删除代码契约 在CLR via C#一书中,我遇到了以下摘录: 而且,由于合同不能对新版本更加严格(不破坏兼容性),您需要 在引入新的虚拟、抽象或接口成员时,应仔细考虑先决条件。 对于后置条件和对象不变量,可以根据条件随意添加和删除契约 表示在虚/抽象/接口成员中,条件表示在重写 成员仅在逻辑上被合并在一起 这让我非常困惑,后置条件和对象不变量,契约可以随意添加和删除。我希望有人建议,后置条件和对象不变量只能变得更

为什么可以为后置条件和对象不变量添加和删除代码契约,而不能为C#中的前置条件添加和删除代码契约

CLR via C#一书中,我遇到了以下摘录:

而且,由于合同不能对新版本更加严格(不破坏兼容性),您需要 在引入新的虚拟、抽象或接口成员时,应仔细考虑先决条件。 对于后置条件和对象不变量,可以根据条件随意添加和删除契约 表示在虚/抽象/接口成员中,条件表示在重写 成员仅在逻辑上被合并在一起

这让我非常困惑,后置条件和对象不变量,契约可以随意添加和删除。我希望有人建议,后置条件和对象不变量只能变得更严格,前提也更严格。我为什么期待这个?因为我可以举一个例子,证明这个建议是错误的。例如

起初我们有一个后置条件,一切正常:

using System.Diagnostics.Contracts;

public sealed class Program
{
    public static void FooBaseContract(int i) 
    {
        Contract.Ensures(i > 0);
    }
}

public class FooBase 
{
    public virtual int i 
    {
        get {return 2;} 
    }
}
public class FooDerived : FooBase
{
    public override int i 
    {
        get {return 4;} 
    }
}
现在,我们决定使后处理条件更加严格:

using System.Diagnostics.Contracts;

public sealed class Program
{
    public static void FooBaseContract(int i) 
    {
        Contract.Ensures(i > 4);
    }
}

public class FooBase 
{
    public virtual int i 
    {
        get {return 2;} 
    }
}
public class FooDerived : FooBase
{
    public override int i 
    {
        get {return 4;} 
    }
}
这肯定会使使用前一后置条件的代码与新后置条件不兼容。这意味着我们通过使后置条件更加严格而失去了向后兼容性

此外,我不明白作者为什么只引用
虚拟、抽象或接口成员
。因为在我上面给出的人为示例中,即使我将代码更改为以下内容(删除所有
虚拟、抽象或接口成员
),也会出现与新代码契约版本不兼容的情况:

那么,有人能简单地解释一下我在这里遗漏了什么吗

更新


正如评论部分所提到的,代码契约是一个不推荐使用的概念。这对我来说没关系,我只是想理解这个想法-在这种情况下,这就是为什么我们可以使后置条件和对象不变量更严格?这与我的常识相矛盾,这意味着以前允许返回某些内容(或对象不变量发生),现在我们声明不再允许返回某些内容,本书作者告诉我,这种情况并没有破坏向后兼容性。

文本中说,条件是“and”在一起这意味着您根本没有删除后置条件和不变量的能力。无论如何编写代码,都只能添加它们

后置条件和不变量是在退出时必须确保的东西。能够增加义务是有道理的。如果您正在添加矛盾,CC应将其标记为后条件冲突


从兼容性和可扩展性的角度来看,基类的用户将得到他们期望的保证。他们可能会得到他们不知道或不关心的额外保证。

评论不用于进一步讨论;这段对话已经结束。
using System.Diagnostics.Contracts;

public sealed class Program
{
    public static void FooBaseContract(int i) 
    {
        Contract.Ensures(i > 4);
    }
}

public class FooBase 
{
    public int i 
    {
        get {return 2;} 
    }
}