День двести шестой. #BestPractices
Советы по разработке типов
4. Разработка интерфейсов
Хотя большинство API лучше всего моделировать с использованием классов и структур, в некоторых случаях интерфейсы являются более подходящим или даже единственным вариантом:
- Реализация эффекта множественного наследования. CLR не поддерживает множественное наследование, но позволяет типам реализовывать один или несколько интерфейсов в дополнение к наследованию от базового класса. Например, IDisposable - это интерфейс, который позволяет типам поддерживать освобождение ресурсов независимо от их собственной иерархии наследования.
- Создание общего интерфейса, который может поддерживаться несколькими типами, включая некоторые значимые типы. Значимые типы не могут наследоваться, но могут реализовывать интерфейсы, поэтому использование интерфейса является единственным вариантом для обеспечения общего поведения.
✅ ИСПОЛЬЗУЙТЕ интерфейс, если вам нужен общий API, который будет поддерживаться набором типов, включая значимые типы.
⚠️ РАССМОТРИТЕ использование интерфейса, если вам необходимо поддерживать функциональность для типов, которые уже наследуются от какого-либо другого типа.
❌ ИЗБЕГАЙТЕ использования маркерных интерфейсов (интерфейсов без членов). Если вам нужно пометить класс как имеющий определенную характеристику (маркер), используйте пользовательский атрибут, а не интерфейс.
✅ ИСПОЛЬЗУЙТЕ хотя бы один тип, реализующий интерфейс. Это помогает проверить реализацию интерфейса. Например, List<T> является реализацией интерфейса IList<T>.
✅ ИСПОЛЬЗУЙТЕ хотя бы один API, использующий каждый определенный вами интерфейс (метод, принимающий интерфейс в качестве параметра или свойство интерфейсного типа). Это помогает проверить реализацию интерфейса. Например, List<T>.Sort использует интерфейс System.Collections.Generic.IComparer<T>.
❌ ИЗБЕГАЙТЕ добавления членов в интерфейс, выпущенный в предыдущей версии, если вы поставляете библиотеку. Это нарушит все реализации этого интерфейса. Вы должны создать новый интерфейс, чтобы избежать проблем при переходе от одной версии к другой.
ЗАМЕЧАНИЕ: Начиная с C#8 в таких случаях для интерфейсных методов можно использовать реализацию по умолчанию.
Продолжение следует…
Источник: https://docs.microsoft.com/en-us/dotnet/standard/design-guidelines/
Советы по разработке типов
4. Разработка интерфейсов
Хотя большинство API лучше всего моделировать с использованием классов и структур, в некоторых случаях интерфейсы являются более подходящим или даже единственным вариантом:
- Реализация эффекта множественного наследования. CLR не поддерживает множественное наследование, но позволяет типам реализовывать один или несколько интерфейсов в дополнение к наследованию от базового класса. Например, IDisposable - это интерфейс, который позволяет типам поддерживать освобождение ресурсов независимо от их собственной иерархии наследования.
- Создание общего интерфейса, который может поддерживаться несколькими типами, включая некоторые значимые типы. Значимые типы не могут наследоваться, но могут реализовывать интерфейсы, поэтому использование интерфейса является единственным вариантом для обеспечения общего поведения.
✅ ИСПОЛЬЗУЙТЕ интерфейс, если вам нужен общий API, который будет поддерживаться набором типов, включая значимые типы.
⚠️ РАССМОТРИТЕ использование интерфейса, если вам необходимо поддерживать функциональность для типов, которые уже наследуются от какого-либо другого типа.
❌ ИЗБЕГАЙТЕ использования маркерных интерфейсов (интерфейсов без членов). Если вам нужно пометить класс как имеющий определенную характеристику (маркер), используйте пользовательский атрибут, а не интерфейс.
✅ ИСПОЛЬЗУЙТЕ хотя бы один тип, реализующий интерфейс. Это помогает проверить реализацию интерфейса. Например, List<T> является реализацией интерфейса IList<T>.
✅ ИСПОЛЬЗУЙТЕ хотя бы один API, использующий каждый определенный вами интерфейс (метод, принимающий интерфейс в качестве параметра или свойство интерфейсного типа). Это помогает проверить реализацию интерфейса. Например, List<T>.Sort использует интерфейс System.Collections.Generic.IComparer<T>.
❌ ИЗБЕГАЙТЕ добавления членов в интерфейс, выпущенный в предыдущей версии, если вы поставляете библиотеку. Это нарушит все реализации этого интерфейса. Вы должны создать новый интерфейс, чтобы избежать проблем при переходе от одной версии к другой.
ЗАМЕЧАНИЕ: Начиная с C#8 в таких случаях для интерфейсных методов можно использовать реализацию по умолчанию.
Продолжение следует…
Источник: https://docs.microsoft.com/en-us/dotnet/standard/design-guidelines/