Интерфейсы тегов используются в Java (очевидным примером является Serializable). C # и даже Java, похоже, отходят от этого, хотя и в пользу атрибутов, которые могут выполнять то же самое, но и делать гораздо больше.
Я все еще думаю, что им есть место в других языках, у которых нет концепции атрибутов, которая есть в .NET и Java.
ETA:
Обычно вы используете это, когда у вас есть интерфейс, который подразумевает реализацию, но вы не хотите, чтобы класс, реализующий интерфейс, фактически должен был предоставить эту реализацию.
Некоторые примеры из реального мира:
Serializable является хорошим примером - он подразумевает, что есть реализация (где-то), которая может сериализовать данные объекта, но, поскольку универсальная реализация для этого доступна, нет необходимости в том, чтобы объект сам реализовывал эту функцию.
Другим примером может быть система кэширования веб-страниц. Скажем, у вас есть объект "Page" и объект "RequestHandler". RequestHandler принимает запрос на страницу, находит / создает соответствующий объект Page, вызывает метод Render () для объекта Page и отправляет результаты в браузер.
Теперь, скажем, вы хотели реализовать кэширование для отображаемых страниц. Но проблема в том, что некоторые страницы являются динамическими, поэтому их нельзя кэшировать. Одним из способов реализации этого было бы использование кешируемых объектов Page для реализации интерфейса «тега» ICacheable (или наоборот, вы могли бы иметь интерфейс INotCacheable). Затем RequestHandler проверит, реализована ли страница ICacheable, и если он это сделал, то после вызова Render () будет кэшировать результаты и обработать эти кэшированные результаты при последующих запросах для этой страницы.