Во время одного из моих исследований тонкостей C # я наткнулся на интересный отрывок, касающийся явной реализации интерфейса.
While this syntax is quite helpful when you need to resolve name clashes,
you can use explicit interface implementation simply to hide more "advanced"
members from the object level.
Разница между разрешением использования object.method()
или требованием применения заклинания ((Interface)object).method()
кажется мне неопытным злым умыслом. Текст отметил , что это будет скрывать метод от Intellisense на уровне объекта, но почему вы хотите сделать это , если это не было необходимо , чтобы избежать конфликтов имен?
c#
design
interfaces
Nathanus
источник
источник
Ответы:
Представьте себе ситуацию, когда интерфейс заставляет класс реализовывать методы, которые на самом деле не имеют смысла как часть класса. Это может часто случаться, когда интерфейсы особенно велики и нарушают принцип разделения интерфейсов.
Этот класс должен реализовывать интерфейс, но вместо того, чтобы загрязнять его хорошо видимый публичный интерфейс методами, которые не имеют смысла, вы можете явно реализовать те методы, которые вы не хотите, чтобы они были явно доступны. Хорошо видимый открытый интерфейс класса - это то, как вы хотите, чтобы класс использовался, и явная реализация существует, когда к классу получают доступ через интерфейс.
источник
IEnumerable<T>
которая ведет себя как объединение двух других. ЕслиIEnumerable<T>
включено свойство, позволяющее определить, было ли его число известным, потенциально бесконечным или нет, вместе с методом для запроса значения счетчика, класс, который объединяет несколькоIEnumerable<T>
и ведет себя как конкатенация, мог бы эффективно сообщать свой счет в том случае, если некоторые из инкапсулированные коллекции знали свое значение.Самым полезным приложением, которое я нашел, является реализация фабрик. Во многих случаях полезно создавать классы, которые являются изменяемыми внутри фабрики, но неизменяемыми для внешних классов. Это может быть легко реализовано в Java с использованием внутренних классов, делая поля и их установщики частными и выставляя получатели только как открытые члены. Однако в C # мне пришлось использовать явные интерфейсы для достижения того же. Я объясню дальше:
В Java внутренний класс И внешний класс могут обращаться к закрытым членам друг друга, что имеет смысл, поскольку классы очень тесно связаны. Они находятся в одном файле кода и, вероятно, разработаны одним и тем же разработчиком. Это означает, что фабрика все еще может получить доступ к закрытым полям и методам внутреннего класса, чтобы изменить их значения. Но внешние классы не смогут получить доступ к этим полям, кроме как через своих общедоступных получателей.
Однако в C # внешние классы не могут получить доступ к закрытым членам внутренних классов, так что концепция напрямую не применима. Я использовал явный интерфейс в качестве обходного пути, определив частный интерфейс во внешнем классе и явно реализовав его во внутреннем классе. Таким образом, только внешний класс может обращаться к методам в этом интерфейсе так же, как это делается в Java (но они должны быть методами, а не полями).
Пример:
Вот для чего я бы использовал явные интерфейсы.
источник
Если класс реализует два интерфейса, которые содержат член с одинаковой подписью, то реализация этого члена в классе приведет к тому, что оба интерфейса будут использовать этот член в качестве своей реализации. В следующем примере все вызовы
Paint
вызывают один и тот же метод. C #Напротив, явная реализация одного (или обоих) из них позволяет вам определять различное поведение для каждого.
источник
Явные интерфейсы удобны, когда какой-либо объект имеет две или более очень разные формы общения.
Например, объект, который поддерживает коллекцию дочерних объектов, которые должны взаимодействовать с родителем.
Есть некоторые действия, которые мы хотим сделать доступными только для внешних абонентов, и некоторые действия, которые мы хотим сделать доступными только для дочерних объектов.
Явные интерфейсы помогают обеспечить это разделение.
источник
Возможно, если у вас есть функциональность, которая была бы полезна для пользователей, но только если вы действительно знаете, что делаете (достаточно, чтобы прочитать документацию, чтобы узнать о функции), но это может сломать ситуацию, если вы этого не сделаете.
Почему вы делаете это, а не предоставляете, скажем, второй «интерфейс расширенных возможностей», я не знаю.
источник
Код обычно читается больше, чем написано, и я использую только Intellisense для быстрого написания кода. Я бы не стал писать код определенным образом, чтобы сделать Intellisense лучше.
Я не особо понимаю, как
((Интерфейс) объект) .method () более читабелен, чем object.method ().
Если бы у меня было много методов для определенного объекта, я мог бы задаться вопросом, является ли это объектом бога или нет, и на самом деле должен быть разбит на несколько более простых объектов.
источник