2015-07-02 3 views
9

Как гласит название: хорошо ли документировать заброшенные исключения для интерфейсов? Существует ли вообще согласованная передовая практика? Я чувствую, что это деталь реализации, которая никак не должна быть включена в интерфейс, но в то же время я считаю, что это ценная информация, которую должен иметь пользователь интерфейса.Является ли хорошей практикой документировать выброшенные исключения для интерфейсов?

Является ли такая рекомендация хорошей практикой, является темой для другого обсуждения, поэтому, чтобы ограничить сферу этого вопроса, предположим, что мы согласились с тем, что документирование кода с комментариями, как это, является хорошей практикой. Здесь, с такими комментариями, я имею в виду комментарии, которые вы можете генерировать, например, документацию или метаданные, а не только «нормальные» комментарии. Примеры включают документацию XML, Javadoc и Doxygen.

Теперь, какой из этих примеров C# является лучшей практикой, если можно даже договориться о какой-либо лучшей практике?

интерфейс без документации исключения:

public interface IMyInterface { 
    /// <summary> 
    /// Does something. 
    /// </summary> 
    void DoSomething(); 
} 

Интерфейс с документацией исключения:

public interface IMyInterface { 
    /// <summary> 
    /// Does something. 
    /// </summary> 
    /// <exception cref="System.Exception">Something went wrong.</exception> 
    void DoSomething(); 
} 
+2

Прежде всего, используйте только комментарии при необходимости. Я даже сомневался в необходимости «Что-то». комментарий. В стороне, я могу реализовать 'IMyInterface' с' DoSomething() ', который ловит« Исключение », что означает, что ваше описание теперь неправильно. Целью интерфейса является контракт. Этот контракт не может обеспечить исключение броска, поэтому его не должно быть. –

+4

@DavidArno В вашем комментарии так много всего плохого. 1) использование '///' не создает нормального комментария, оно создает метаданные, на которые вы можете создавать документацию. 2) Вполне приемлемо, чтобы возможные известные исключения были частью контракта. 3) «Что-то». это всего лишь пример текста для этого фрагмента. –

+0

@ScottChamberlain, ваш комментарий аккуратно подсвечивает, почему я голосовал, чтобы закрыть этот вопрос как «в основном основанный на мнениях». Вы думаете, что я ошибаюсь; Я думаю, вы ошибаетесь. Это не делает для хорошего контента SO ... –

ответ

10

Интерфейсы контрактов, если часть этого договора включает в себя ситуацию, выброшенное исключение вы должны обязательно включить его в вашей документации. Вы можете видеть примеры исключений, задокументированных в интерфейсах по всей платформе .NET, например, IEnumerator имеет немало. (Текст retreived щелкнув правой кнопкой мыши на объявлении IEnumerator и навигации на «представление метаданных»)

public interface IEnumerator 
    { 
    /// <summary> 
    /// Advances the enumerator to the next element of the collection. 
    /// </summary> 
    /// 
    /// <returns> 
    /// true if the enumerator was successfully advanced to the next element; false if the enumerator has passed the end of the collection. 
    /// </returns> 
    /// <exception cref="T:System.InvalidOperationException">The collection was modified after the enumerator was created. </exception><filterpriority>2</filterpriority> 
    bool MoveNext(); 
    /// <summary> 
    /// Sets the enumerator to its initial position, which is before the first element in the collection. 
    /// </summary> 
    /// <exception cref="T:System.InvalidOperationException">The collection was modified after the enumerator was created. </exception><filterpriority>2</filterpriority> 
    void Reset(); 
    /// <summary> 
    /// Gets the current element in the collection. 
    /// </summary> 
    /// 
    /// <returns> 
    /// The current element in the collection. 
    /// </returns> 
    /// <filterpriority>2</filterpriority> 
    object Current { get; } 
    } 
+0

Я искал примеры, но не нашел ни одного +1 –

+0

Идеальный пример того, как ** не ** писать интерфейс. Вы должны пробираться сквозь бессмысленное дерьмо, например «Получает текущий элемент в коллекции». «Текущий элемент в коллекции». для доступа к фактическому содержимому 'object Current {get; } '. -1 в любом случае подразумевает, что это хорошая практика. –

+3

@DavidArno: почему бессмысленно дерьмо видеть в intellisense, что 'Current' возвращает« текущий элемент в коллекции »или что' MoveNext' генерирует исключение, если «коллекция была изменена после создания счетчика», когда вы собираетесь использовать это свойство? Это чрезвычайно ценные инфор мации. –

3

Интерфейс только определяет контракт операций делать не так, как они реализуются. Рассмотрим следующий пример:

void Sort(SortOrder order); 

Вы могли бы возникнуть соблазн добавить комментарий throws ArgumentNullException if order is null, но что произойдет, если реализатор интерфейса решает, что получение нуль на SortOrder означает, что он должен использовать по умолчанию SortOrder? (неправильное решение, но возможное). Это должно быть правильным решением для одного интерфейса, и если это не вариант, чтобы решить такие вещи, то вы должны предложить абстрактный базовый класс, который генерирует исключение вместо интерфейса.

Добавление исключений к интерфейсам подобно тому, как наследование интерфейсов наследуется от интерфейса IDisposable. Эти вещи являются деталями реализации, которые не должны вникать в определение интерфейса.

+1

Это зависит от многого. Есть хороший пример, когда имеет смысл включать возможные исключения в интерфейс, как показал Скотт. Вот еще один: 'IList list = new string [] {" foo "}; list.Add ("bah"); '. Если вы наведете над «Добавить», вам сообщают, что этот метод может вызывать «NotSupportedException», если базовая коллекция доступна только для чтения или фиксированного размера (что в данном случае является истинным). Это также [документально] (https://msdn.microsoft.com/en-us/library/system.collections.ilist.add (v = vs.110) .aspx). –

+1

@TimSchmelter, бросая «NotSupportedException», не сможет выполнить контракт интерфейса, поскольку это, вероятно, самый очевидный пример нарушения LSP. Кажется, вы оба хотите, чтобы интерфейсы использовали комментарии для наложения контрактов на класс и использования комментариев, чтобы позволить классам избегать этих контрактов. Подобные злоупотребления комментариями являются слюной, чем класс, полный готосов. –

+0

Я согласен, исключение NotSupportedException выглядит как ярлык, чтобы избежать создания правильных интерфейсов, таких как IReadOnlyList. –

Смежные вопросы