Подтвердить что ты не робот

Интерфейс без каких-либо членов - плохая практика?

Возможный дубликат:
Какова цель интерфейса маркера?

Неправильная практика создания полностью пустого интерфейса, например:

public interface ISomething
{
}

Есть случай, когда я хотел бы обрабатывать определенные объекты по-другому, чем другие, но я не требую никакого нового поведения.

4b9b3361

Ответ 1

Я лично считаю, что пустые интерфейсы не очень хороши.

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

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

Избегайте использования интерфейсов маркеров (интерфейсы без членов).

Пользовательские атрибуты предоставляют способ маркировки типа. Дополнительные сведения о настраиваемых атрибутах см. В разделе "Написание пользовательских атрибутов". Пользовательские атрибуты предпочтительнее, если вы можете отложить проверку атрибута до тех пор, пока код не будет выполнен. Если ваш сценарий требует проверки времени компиляции, вы не можете выполнить это руководство.

Ответ 2

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

Ответ 3

Я бы сказал, что атрибут лучше, но есть примеры в .NET-сетке пустых интерфейсов (например, INamingContainer - http://msdn.microsoft.com/en-us/library/system.web.ui.inamingcontainer.aspx). Я всегда задавался вопросом, почему это было сделано таким образом - кто-нибудь знает?

Ответ 4

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

В приложении asp.net mvc, с которым я работал в последнее время, у меня была основная операция (код отслеживания), которую я хотел выполнить почти по каждому запросу (но не по запросу и по запросу ajax или по странице администратора). Я добавил операцию на базовый контроллер и выполнил ее в методе ExecuteCore. Для нескольких ситуаций, которые я не хотел запускать, я установил флаг в производном контроллере, чтобы он не запускал его.

Это не так чисто и элегантно, как атрибут, но его намного проще реализовать.

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

Ответ 5

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

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

Тем не менее, если я сравню первый раз, когда я столкнулся с пустым интерфейсом (я помню, что это была определенно Java около 2000), с первого раза я столкнулся с атрибутом (веб-сервисы С#) - я смог вывести цель одного, а другого заставили меня перейти в режим обучения...

Ответ 6

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

Думаю, вы могли бы считать это абстрактным базовым классом?