Интерфейс не должен иметь свойств?

Мой офисный коллега сказал мне сегодня, что это плохая практика использования свойств в интерфейсах. Он был красным, что в некоторых статьях MSDN, которые я не смог найти (ну, я несколько раз пытался использовать Google, возможно, с неправильными ключевыми словами). Он также сказал мне, что только методы должны быть в интерфейсе. Теперь я знаю, что это не строгое правило, так как, очевидно, в .net вы можете сделать подпись свойства в интерфейсе и скомпилировать его.

Но это правда, что это плохая практика/дизайн/oop? И почему?

Было бы полезно указать на нужную литературу или веб-ресурс.

Спасибо

Ответы

Ответ 1

Я просто добавлю свой голос здесь - я никогда не сталкивался с этой рекомендацией. Свойство эффективно представляет собой пару методов get/set.

Как и любое другое дизайнерское решение. Если это действительно имеет смысл; если это подходит для проектируемой системы, если это не вызывает проблем с обслуживанием, если это не вызывает проблем с производительностью, не должно быть причин, по которым вы не можете этого сделать.

Ответ 2

Я никогда не сталкивался с тем, что кто-либо делал это выражение, и я не вижу веских оснований для этого. Структура .NET полна интерфейсов со свойствами.

Ответ 3

Существует широко признанный термин "запах кода". Я предлагаю ввести понятие "запах программиста" - если кто-то настаивает на каком-то правиле, но не может объяснить, почему - это запах. Ваш коллега должен уметь объяснить, почему свойства в интерфейсе плохие. Если он не может - он, вероятно, ошибается, даже если статья, на которую он ссылается, прав.

В этой статье может быть речь о некоторых конкретных типах интерфейсов, может быть, это связано с COM и интероперабельностью или что-то еще. Или он может быть просто ошибался. Понимание правил и возможность их объяснения является важной частью использования правил.

Ответ 4

Интерфейс - это контракт для класса для реализации, и я не вижу причин, по которым свойства должны быть исключены из такого контракта. Кроме того, свойства являются неотъемлемой частью .NET.

В качестве примера: ICollection<T> имеет как Count, так и IsReadOnly.

Ответ 5

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

Ответ 6

Единственный способ, о котором я могу думать, почему свойства являются плохими для интерфейсов, заключается в определении интерфейсов для служб (таких как WCF, WebServices, Remoting), размещенных на разных компьютерах или доменах приложений.

Свойства причины предполагают, что они быстрые (например, получение и установка значений), что неверно для служб, из-за активности сети и сериализации. Метод explizit для получения или установки значений в интерфейсах служб подразумевает, что для завершения операции может потребоваться некоторое время.

Ответ 7

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

Ответ 8

Практически свойство имеет две функции: одну для получения значения и одну для установки значения. Хотя свойства являются первоклассными "функциями" С#, это все еще верно.

Почему не допускаются свойства в интерфейсах?

Ответ 9

Я не вижу причин не иметь Свойства как часть вашего интерфейса. Как еще вы могли бы реализовать доступ к элементам данных? Получите методы и установите методы вместо свойств. Это было бы просто уродливо и поэтому в 1990-х годах.

Ответ 10

Единственный недостаток, который я могу видеть в свойствах по сравнению с методами, заключается в том, что, хотя нет проблем с интерфейсом с методом get, интерфейсом с заданным методом и интерфейсом, который объединяет эти два (сценарий, который позволил бы максимально гибко с ковариацией и контравариантностью), свойства не сочетаются хорошо. Я не уверен, почему свойство read-write не просто считается таким же, как свойство read и свойство write, но это не так. Если интерфейс будет поддерживать свойство только для чтения и свойство только для записи с тем же именем, любая попытка доступа к свойствам через объединенный интерфейс не будет выполняться на основе заявленной двусмысленности.

Ответ 11

Плохая конструкция, поскольку вы загрязняете пространство переменных реализации, которое используется для хранения состояния с переменными, которые используются как часть договора класса.

Ответ 12

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

Ответ 13

Я вижу, что это вопрос.Net; однако, мышление может исходить из опыта Java. Это напоминает мне пункт 22 из Effective Java: используйте интерфейсы только для определения типов.

Эта рекомендация не запрещает все свойства в интерфейсах. Он специально обращается к интерфейсам, содержащим только свойства.

Когда класс реализует интерфейс, интерфейс служит типом, который можно использовать для ссылки на экземпляры класса. То, что класс реализует интерфейс, должно поэтому сказать что-то о том, что клиент может сделать с экземплярами класса. Неуместно определять интерфейс для каких-либо других целей.

Одним из видов интерфейса, который не проходит этот тест, является так называемый постоянный интерфейс. Такой интерфейс не содержит методов; он состоит исключительно из статических полей финала...

Постоянный шаблон интерфейса - плохое использование интерфейсов. То, что класс использует некоторые константы внутри, является деталью реализации. Реализация постоянного интерфейса вызывает утечку этой детали реализации в экспортируемый API-интерфейс класса... это представляет обязательство: если в будущем выпуске класс будет изменен, так что ему больше не нужно будет использовать константы, он все равно должен реализовать интерфейс для обеспечить бинарную совместимость. Если нефинальный класс реализует постоянный интерфейс, все его подклассы будут иметь свои пространства имен, загрязненные константами в интерфейсе.

Конечно, сама Java (и, вероятно, С#) содержит примеры этих постоянных интерфейсов. В книге также об этом говорится.

В библиотеках платформы Java есть несколько постоянных интерфейсов... Эти интерфейсы должны рассматриваться как аномалии и не должны эмулироваться.

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