Я использую Кодовые контракты вместе с Расширениями Редактора контрактных кодов VS2010 надстройка.У меня есть класс, который реализует интерфейс IEnumerable<T>
, и я реализовал блок итератора для метода GetEnumerator()
.Над ним я вижу следующий унаследованный контракт:
Я понимаю первое и третье требование контракта - GetEnumerator()
никогда не должен возвращать ноль, и он никогда не должен вызыватьпобочный эффект.Но что означает второе требование контракта?Что это за Model
свойство IEnumerator<T>
и IEnumerable
?
РЕДАКТИРОВАТЬ: Как указал Damien_The_Unbeliever в своем комментарии, контракт на IEnumerable<T>
и IEnumerator<T>
находится в отдельном файле, справочной сборке контрактов.Используя Reflector , при разборке контракта этих двух интерфейсов (полный код здесь ), вы можете увидеть следующее:
[return: Fresh]
[Escapes(true, false), Pure, GlobalAccess(false)]
public IEnumerator GetEnumerator()
{
IEnumerator enumerator;
Contract.Ensures((bool) (Contract.Result<IEnumerator>() != null), null, "Contract.Result<IEnumerator>() != null");
Contract.Ensures((bool) (Contract.Result<IEnumerator>().Model == this.Model), null, "Contract.Result<IEnumerator>().Model == this.Model");
Contract.Ensures((bool) (Contract.Result<IEnumerator>().CurrentIndex == -1), null, "Contract.Result<IEnumerator>().CurrentIndex == -1");
return enumerator;
}
Интересно,в GetEnumerator()
есть дополнительный контракт, который не отображается расширением редактора:
Contract.Result<IEnumerator>().CurrentIndex == -1
и некоторые дополнительные загадки (такие как атрибуты Fresh
, Escapes
и GlobalAccess
).