Diseño de interfaces
Nota:
Este contenido se ha copiado con permiso de Pearson Education, Inc. de Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries, 2ª edición. Esa edición se publicó en 2008 y el libro se ha revisado completamente en la tercera edición. Parte de la información de esta página puede estar obsoleta.
Aunque la mayoría de las API se modelan mejor mediante clases y structs, hay casos en los que las interfaces son más adecuadas o son la única opción.
CLR no admite la herencia múltiple (es decir, las clases CLR no pueden heredar de más de una clase base), pero permite que los tipos implementen una o varias interfaces además de heredar de una clase base. Por lo tanto, las interfaces se usan a menudo para lograr el efecto de la herencia múltiple. Por ejemplo, IDisposable es una interfaz que permite que los tipos admitan la eliminación independientemente de cualquier otra jerarquía de herencia en la que deseen participar.
La otra situación en la que la definición de una interfaz es adecuada es crear una interfaz común que pueda ser compatible con varios tipos, incluidos algunos tipos de valor. Los tipos de valor no pueden heredar de tipos distintos de ValueType, pero pueden implementar interfaces, por lo que el uso de una interfaz es la única opción para proporcionar un tipo base común.
✔️ DEBE definir una interfaz si necesita que una API común sea compatible con un conjunto de tipos que incluye tipos de valor.
✔️ PLANTÉESE la posibilidad de definir una interfaz si necesita admitir su funcionalidad en tipos que ya heredan de algún otro tipo.
❌ EVITE usar interfaces de marcador (interfaces sin miembros).
Si necesita marcar una clase como una característica específica (marcador), en general, use un atributo personalizado en lugar de una interfaz.
✔️ DEBE proporcionar al menos un tipo que es una implementación de una interfaz.
Esto ayuda a validar el diseño de la interfaz. Por ejemplo, List<T> es una implementación de la interfaz IList<T>.
✔️ DEBE proporcionar al menos una API que consuma cada interfaz que defina (un método que toma la interfaz como un parámetro o una propiedad con el tipo de interfaz).
Esto ayuda a validar el diseño de la interfaz. Por ejemplo, List<T>.Sort consume la interfaz System.Collections.Generic.IComparer<T>.
❌ NO agregue miembros a una interfaz que se haya enviado anteriormente.
Si lo hace, se interrumpirán las implementaciones de la interfaz. Debe crear una nueva interfaz con el fin de evitar problemas de control de versiones.
A excepción de las situaciones descritas en estas instrucciones, debe, en general, elegir clases en lugar de interfaces al diseñar bibliotecas reutilizables de código administrado.
Portions © 2005, 2009 Microsoft Corporation. Todos los derechos reservados.
Material reimpreso con el consentimiento de Pearson Education, Inc. y extraído de Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries, 2nd Edition (Instrucciones de diseño de .NET Framework: convenciones, expresiones y patrones para bibliotecas .NET reutilizables, 2.ª edición), de Krzysztof Cwalina y Brad Abrams, publicado el 22 de octubre de 2008 por Addison-Wesley Professional como parte de la serie Microsoft Windows Development.