您好我正在尝试为setter制定一个简单的代码合同,声明DateTime必须至少有十五年的历史。
如果我在合同类的成员中进行验证,编译器会产生
合同类' TypeValidation.CodeContract.CitizenContract'引用成员' TypeValidation.CodeContract.CitizenContract.BeGreaterThanFiveTeenYearsOld(System.DateTime)'这不是被注释的抽象类/接口的一部分。
我的代码是:
[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;
}
}
我不明白为什么抱怨,谁能解释为什么? 提前致谢
答案 0 :(得分:2)
您无法添加新成员,因为合同是在ICitizen
的任意实例上评估的,而不是CitizenContract
的实例,而那些不具备该方法的合同。因为您的方法实际上不需要实例,所以可以将其设为static
。这不足以使错误无声,但您可以将方法移动到另一个类。此外,该方法应为public
和[Pure]
:
public static class CitizenContractHelpers {
[Pure]
public static bool MoreThanFifTeenYearsOld(DateTime dateToValidate) {
…
}
}
此外,合同类应为abstract
。
阅读http://research.microsoft.com/en-us/projects/contracts/userdoc.pdf处的手册,您需要了解所有内容。
这个例子不能很好地使用Code Contracts,它应该用于查找编程错误。合同的有效性取决于程序员通常无法控制的环境DateTime.Now
(用户可以在使用您的应用程序时更改计算机上的时间)。所以在这种情况下,实现中的简单if-throw检查会更好。