2015-09-28 2 views
1

Привет, я пытаюсь сделать простой контракт на код для сеттера, в котором указано 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

Вы пробовали «чистое решение»? Похоже, вы переименовали один из ваших методов проверки, но он кэшируется. –

+0

Я думаю, что вам что-то не хватает - я не вижу BeGreaterThanFiveTeenYearsOld в вашем файле, даже когда компилятор жалуется на эту переменную/prop –

+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, есть все, что вам нужно знать.

Этот пример не подходит для использования кодовых контрактов, которые необходимо использовать для поиска ошибок программирования. Срок действия вашего контракта зависит от среды DateTime.Now, которую программист обычно не контролирует (пользователь может изменить время на своем компьютере при использовании вашего приложения). Таким образом, в этом случае простая проверка if-throw в реализациях будет лучше.

+0

Спасибо, что это было действительно полезно –