合同 class 引用的成员不是被注释的摘要 class/interface 的一部分

Contract class references member which is not part of the abstract class/interface being annotated

您好,我正在尝试为 setter 制定一个简单的代码合同,其中规定 DateTime 必须至少有 15 年历史。

如果我在合约成员中进行验证 class 编译器会产生

Contract class 'TypeValidation.CodeContract.CitizenContract' references member 'TypeValidation.CodeContract.CitizenContract.BeGreaterThanFiveTeenYearsOld(System.DateTime)' which is not part of the abstract class/interface being annotated.

我的代码是:

[ContractClass(typeof(CitizenContract))]
public interface ICitizen
{
    int Age { get; set; }
    DateTime BirtDate { get; set; }
    string Name { get; set; }
}

[ContractClassFor(typeof(ICitizen))]
public class CitizenContract : ICitizen
{
    public int Age
    {
        get { return default(int); }
        set
        {

            Contract.Requires<ArgumentOutOfRangeException>(value > 15, "Age must be sixteen or greater.");
        }
    }


    public DateTime BirtDate
    {
        get { return default(DateTime); }
        set
        {
            Contract.Requires<ArgumentOutOfRangeException>(MoreThanFifTeenYearsOld(value), "The birthdate has to be a minimum of sixteen years old");
        }
    }

    public string Name
    {
        get { return default(string); }
        set
        {
            Contract.Requires<ArgumentNullException>(!string.IsNullOrWhiteSpace(value), "Name Cant be null or empty.");
            Contract.Requires<ArgumentOutOfRangeException>(value.Length >= 3 && value.Length <= 50, "Name has to have between three and fifty.");
        }
    }

    bool MoreThanFifTeenYearsOld(DateTime dateToValidate)
    {

        if (dateToValidate == default(DateTime)) return false;

        DateTime zeroTime = new DateTime(1, 1, 1);
        var currentTime = DateTime.Now;
        if (currentTime <= dateToValidate) return false;
        TimeSpan span = currentTime - dateToValidate;
        return ((zeroTime + span).Year - 1) >= 16;
    }
}

我不明白它为什么抱怨,谁能解释为什么? 提前致谢

您不能添加新成员,因为合同是在 ICitizen 的任意实例上评估的,而不是在 CitizenContract 的实例上评估的,并且那些没有该方法。因为你的方法实际上并不需要实例,所以你可以把它设为static。这不足以消除错误,但您可以将方法移至另一个 class。此外,该方法应为 public[Pure]:

public static class CitizenContractHelpers {
    [Pure]
    public static bool MoreThanFifTeenYearsOld(DateTime dateToValidate) {
    …
    }
}

此外,合同 class 应该是 abstract

阅读 http://research.microsoft.com/en-us/projects/contracts/userdoc.pdf 上的手册,这里有您需要了解的一切。

这个例子不是很好用Code Contracts,应该用来找程序bug。您的合同的有效性取决于程序员通常无法控制的环境 DateTime.Now(用户可以在使用您的应用程序时更改其计算机上的时间)。所以在这种情况下,在实现中进行简单的 if-throw 检查会更好。