Контракт интерфейса
От: Аноним  
Дата: 09.04.12 06:59
Оценка:
Обладает ли следующий интерфейс допустимым контрактом:
 public interface IContainer<T>
  {
      IEnumerable<T> Items { get; }
      int Count { get; }
  }


Ну понятно, Count я могу определить через Items, а вот Items как бы я определить не могу. Значит контракт не допустим? Где вообще,уважаемые, можно про такие вещи почитать?
Спасибо.
Re: Контракт интерфейса
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 09.04.12 07:53
Оценка: 8 (2)
Здравствуйте, Аноним, Вы писали:

А>Обладает ли следующий интерфейс допустимым контрактом:

А>
А> public interface IContainer<T>
А>  {
А>      IEnumerable<T> Items { get; }
А>      int Count { get; }
А>  }
А>


А>Ну понятно, Count я могу определить через Items, а вот Items как бы я определить не могу. Значит контракт не допустим? Где вообще,уважаемые, можно про такие вещи почитать?

А>Спасибо.

На лице непонимание "контракта" и "интерфейса".
1) Интерфейс класса то что предоставляет класс потребителю с точки зрения языка, то есть в C# интерфейс — набор свойств и методов с именем и типами.
2) Контракт — дополнительные условия, налагаемые на интерфейс. например то что Count всегда положителен, а Items не возвращает null.
Re: Контракт интерфейса
От: Sharov Россия  
Дата: 09.04.12 07:59
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Ну понятно, Count я могу определить через Items,

Не всегда. IEnumerable не имеет св-ва Count.Если наследующая IEnumerable коллекция не реализует Count, то без непосредственного итерирования по всем элементам узнать Count не удасться.

>а вот Items как бы я определить не могу.

Это почему?

>Значит контракт не допустим?

Если компилятор пропускает, значит допустим.
Кодом людям нужно помогать!
Re: Контракт интерфейса
От: Аноним  
Дата: 29.04.12 05:40
Оценка:
Здравствуйте, Аноним, Вы писали:
Это особенности языка. например из такого интерфейса
public interface Locker {
  void Lock();
  void Unlock();
}

совершенно не очевидно можно ли lock-ать вложено или нет.
в таких случаях можно использовать комментарии
Если мало комментарием то кидай исключения и используй тесты.
Re[2]: Контракт интерфейса
От: SergeyT. США http://sergeyteplyakov.blogspot.com/
Дата: 04.05.12 20:07
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Это особенности языка. например из такого интерфейса

А>
А>public interface Locker {
А>  void Lock();
А>  void Unlock();
А>}
А>

А>совершенно не очевидно можно ли lock-ать вложено или нет.
А>в таких случаях можно использовать комментарии
А>Если мало комментарием то кидай исключения и используй тесты.

В принципе, в тех же дот-нетах, контракты можно определить и более формально:

[ContractClass(typeof(LockerContracts))] // указываем контракт
public interface Locker {
// Без дополнительного публичного свойства никак,
// вызывающий код должен понимать, какие контракты налагаются каждым
// методом и должен иметь возможность проверить выполнимость предусловия
bool Locked {get;}
void Lock();
void Unlock();
}

// В .net-е контракты указываются не с помощью атрибутов (они слишком слабовыразительны для этого)
// а с помощью отдельных классов, реализующих требуемый интерфейс
internal abstract class LockerContracts : Locker
{
  public bool Locked {get {throw new NotImplementedException;}}
  public void Lock() {
    // Все, теперь клиенты будут знать, что дважды локать нельзя
    // в противном случае - это баг со всеми вытекающими (ассертом или
    // исключением в рантайме)
    Contract.Requires(!Locked, "We can't acquire lock twice");
  }

  public void Unlock() {
     // Здесь картина аналогична, попытка заанлокать незалоченное приведет к беде
     Contract.Requires(Locked, "We can't release free lock!");
  }
}


Теперь можно на это дело натравить статический анализатор, который еще и во время компиляции (точнее посткомпиляции) сможет отловить проблемы.
Re: Контракт интерфейса
От: SergeyT. США http://sergeyteplyakov.blogspot.com/
Дата: 04.05.12 20:23
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Обладает ли следующий интерфейс допустимым контрактом:

А>
А> public interface IContainer<T>
А>  {
А>      IEnumerable<T> Items { get; }
А>      int Count { get; }
А>  }
А>


А>Ну понятно, Count я могу определить через Items, а вот Items как бы я определить не могу. Значит контракт не допустим? Где вообще,уважаемые, можно про такие вещи почитать?

А>Спасибо.

Ну, для начала о контрактах вообще можно почитать прямо тут: "Проектирование по контракту"
Автор(ы): Тепляков Сергей Владимирович
Дата: 13.09.2010
Проектирование по контракту – это мощная техника разработки программного обеспечения (ПО), которая путем формализации взаимоотношений между компонентами позволяет создавать качественное, надежное и расширяемое ПО. В данной статье рассматриваются теоретические аспекты проектирования по контракту, изначально изложенные Бертраном Мейером, которые позволят понять всю ценность этой методики при разработке ПО.
.

Ну а в данном конкретном случае мне не понятно, зачем вообще городить огород, и не воспользоваться нужным типом коллекции.
Например, начиная с .net 4.5 нас осчастливят наконец-то интерфейсом IReadonlyList:

public interface IReadOnlyList<out T> : IEnumerable<T>, IEnumerable
{
    int Count { get; }
    T this[int index] { get; }
}


Еще можно просто изменить тип возвращаемого значения на ICollection<T>, или на ReadonlyCollection<T>, если знаете, что он точно не будет изменяться.

З.Ы. Существующие типы сами по себе являются отличным выразительным средством задания контракта и прибегать к другим уловкам стоит тогда, когда этой выразительности недостаточно.
З.Ы.Ы. Да и вообще, мне не совсем понятно, о каком контракте здесь может идти речь, кроме как что свойство Count должно возвращать количество элементов в свойстве Items. Если это действительно так нужно, то в терминах Code Contracts это можно выразить, но вопрос: нужно ли?
Re[2]: Контракт интерфейса
От: artelk  
Дата: 05.05.12 09:14
Оценка:
Здравствуйте, SergeyT., Вы писали:

ST>начиная с .net 4.5 нас осчастливят наконец-то интерфейсом IReadonlyList:

Вау! Неужто дождались?!
Re[3]: Контракт интерфейса
От: Аноним  
Дата: 05.05.12 21:27
Оценка:
Здравствуйте, SergeyT., Вы писали:

...
ST>В принципе, в тех же дот-нетах, контракты можно определить и более формально:
ST>[ContractClass(typeof(LockerContracts))] // указываем контракт
ST>public interface Locker {
...
ST>internal abstract class LockerContracts : Locker
...
ST>


ST>Теперь можно на это дело натравить статический анализатор, который еще и во время компиляции (точнее посткомпиляции) сможет отловить проблемы.


Здорово, но работает начиная с framework4
http://msdn.microsoft.com/en-us/library/system.diagnostics.contracts.contract.aspx
Re[3]: Контракт интерфейса
От: SergeyT. США http://sergeyteplyakov.blogspot.com/
Дата: 06.05.12 06:47
Оценка: +1
Здравствуйте, artelk, Вы писали:

A>Здравствуйте, SergeyT., Вы писали:


ST>>начиная с .net 4.5 нас осчастливят наконец-то интерфейсом IReadonlyList:

A>Вау! Неужто дождались?!

Хотя не понятно, почему нас не осчастливят IReadOnlyCollection-ом, все же IReadonlyList содержит индексатор, что налагает серьезные ограничения на реализующую его коллекцию.
Re[4]: Контракт интерфейса
От: artelk  
Дата: 08.05.12 21:20
Оценка:
Здравствуйте, SergeyT., Вы писали:

ST>Здравствуйте, artelk, Вы писали:


A>>Здравствуйте, SergeyT., Вы писали:


ST>>>начиная с .net 4.5 нас осчастливят наконец-то интерфейсом IReadonlyList:

A>>Вау! Неужто дождались?!

ST>Хотя не понятно, почему нас не осчастливят IReadOnlyCollection-ом, все же IReadonlyList содержит индексатор, что налагает серьезные ограничения на реализующую его коллекцию.


Так ведь нужно же что-то оставить, что можно будет добавить в .net 6.0 и 7.0
Или просто не догадались . Интересно, есть ли шанс, что они таки воткнут IReadOnlyCollection между IReadonlyList и IEnumerable?

public interface IReadOnlyCollection<out T> : IEnumerable<T>, IEnumerable
{
  int Count { get; }
}

public interface IReadOnlyList<out T> : IReadOnlyCollection<T>
{
  T this[int index] { get; }
}

Может было задето чье-то эстетическое чувство при виде интерефейсов из одного метода?
Или может побоялись полностью взорвать мозг разработчикам, которые будут ожидать, что IReadOnlyCollection — это интерфейс класса ReadOnlyCollection, который, сейчас реализует IList ( ), а в .net 4.5 будет реализовывать IReadOnlyList...
Re[5]: Контракт интерфейса
От: artelk  
Дата: 12.05.12 12:07
Оценка:
Здравствуйте, artelk, Вы писали:

A>Здравствуйте, SergeyT., Вы писали:


ST>>Хотя не понятно, почему нас не осчастливят IReadOnlyCollection-ом, все же IReadonlyList содержит индексатор, что налагает серьезные ограничения на реализующую его коллекцию.

Вот что подумалось: у интерфейса IEnumerable<T> есть метод-расширение Count(). Если посмотреть его реализацию, то видно, что для объектов, реализующих ICollection<T>, он обращается к их свойству Count, вместо прохождения по всем элементам. Т.е. IReadOnlyCollection<T>, возможно, избыточен. С другой стороны, если у нас есть некий метод SomeMethod(IEnumerable<T>), в его теле мы не должны полагаться на то, что метод Count() будет выполняться эффективно и для такого случая лучше иметь специальный интерфейс IReadOnlyCollection<T>/ICountableEnumerable<T>/etc.

A>Интересно, есть ли шанс, что они таки воткнут IReadOnlyCollection между IReadonlyList и IEnumerable?

Запостил это в качестве идеи сюда: http://visualstudio.uservoice.com/forums/121579-visual-studio/suggestions/2845869-ireadonlycollection-t-
Вдруг поможет.
Re[6]: Контракт интерфейса
От: artelk  
Дата: 05.06.12 12:29
Оценка:
Здравствуйте, artelk, Вы писали:

A>Здравствуйте, artelk, Вы писали:


A>>Интересно, есть ли шанс, что они таки воткнут IReadOnlyCollection между IReadonlyList и IEnumerable?

A>Запостил это в качестве идеи сюда: http://visualstudio.uservoice.com/forums/121579-visual-studio/suggestions/2845869-ireadonlycollection-t-
A>Вдруг поможет.
Вау:
Однако IList<T> остался прежним
Голосуем сюда
Re[4]: Контракт интерфейса
От: Nose Россия  
Дата: 23.06.12 12:55
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здорово, но работает начиная с framework4

А>http://msdn.microsoft.com/en-us/library/system.diagnostics.contracts.contract.aspx

Неправда, в 4 оно встроено, для 3.5 можно отдельно скачать и использовать http://research.microsoft.com/en-us/projects/contracts/
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.