"Абстрактный" интерфейс в С#

Это академический вопрос. Возможно, за этим стоит проблема X-Y, которую я могу опубликовать отдельно позже. Но я на самом деле особенно заинтересован в академическом вопросе здесь.


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

Возможно, у меня есть IFooRepository, IBarRepository и т.д., и я могу объявить IRepository<TEntity>.

Или у меня есть IHappyBot, ISadBot, IConfusedBot, все из которых имеют IBot.

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

Если бы мы говорили об иерархии классов, а не интерфейсах, я бы сказал: "Ах... базовая вещь - абстрактный класс".

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

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


В основном я забочусь о С#, но если эта особенность существует на других основных языках, интересно было бы услышать об этом.

Ответ 1

Философский вопрос в ответ возможно - Но почему класс не сможет реализовать IBot, если он захочет?

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

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

Абсолютный класс имеет смысл, потому что иногда абстрактному классу необходимы заполняемые отверстия реализации (абстрактные методы и т.д.). Это не относится к интерфейсу.

Ответ 2

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

Если вы действительно этого хотите, вы можете ввести класс атрибута Атрибут, скажем [AbstractInterface], но я думаю, что использование этого будет очень ограниченным (и подозрительным).

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