合同 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 检查会更好。
您好,我正在尝试为 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 检查会更好。