Diseño de propiedades
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 las propiedades son técnicamente muy similares a los métodos, son bastante diferentes en cuanto a sus escenarios de uso. Deberían verse como campos inteligentes. Tienen la sintaxis de llamada de los campos y la flexibilidad de los métodos.
✔️ CREE solo propiedades get si no debe permitirse que el llamador cambie el valor de la propiedad.
Tenga en cuenta que si el tipo de la propiedad es un tipo de referencia mutable, el valor de propiedad se puede cambiar incluso si la propiedad solo es get.
❌ NO proporcione solo propiedades set o propiedades en las que el establecedor tenga una accesibilidad más amplia que el captador.
Por ejemplo, no use propiedades con un establecedor público y un captador protegido.
Si no se puede proporcionar el captador de propiedades, implemente la funcionalidad como método en su lugar. Considere la posibilidad de empezar el nombre del método por Set
y siga con el nombre que le habría dado a la propiedad. Por ejemplo, AppDomain tiene un método llamado SetCachePath
en lugar de tener solo una propiedad set denominada CachePath
.
✔️ PROPORCIONE valores predeterminados razonables de todas las propiedades, asegurándose de que los valores predeterminados no dan lugar a una vulnerabilidad de seguridad ni a un código tremendamente ineficaz.
✔️ PERMITA que las propiedades se establezcan en cualquier orden, incluso si el resultado es un estado no válido temporal del objeto.
Es común que dos o más propiedades estén interrelacionadas con un punto en el que algunos valores de una propiedad podrían no ser válidos dados los valores de otras propiedades en el mismo objeto. En tales casos, las excepciones resultantes del estado no válido se deben posponer hasta que el objeto utilice realmente las propiedades interrelacionadas de forma conjunta.
✔️ CONSERVE el valor anterior si un establecedor de propiedades inicia una excepción.
❌ EVITE iniciar excepciones desde captadores de propiedades.
Los captadores de propiedades deben ser operaciones simples y no deben tener ninguna condición previa. Si un captador puede iniciar una excepción, es probable que haya que rediseñarlo para que sea un método. Tenga en cuenta que esta regla no se aplica a los indizadores, donde esperamos excepciones como resultado de la validación de los argumentos.
Diseño de propiedades indizadas
Una propiedad indizada es una propiedad especial que puede tener parámetros y a la que se puede llamar con una sintaxis especial similar a la indexación de matrices.
Las propiedades indexadas se conocen normalmente como indizadores. Los indizadores deben usarse solo en las API que proporcionan acceso a los elementos de una colección lógica. Por ejemplo, una cadena es una colección de caracteres y el indizador de System.String se agregó para tener acceso a sus caracteres.
✔️ CONSIDERE la posibilidad de usar indizadores para proporcionar acceso a los datos almacenados en una matriz interna.
✔️ CONSIDERE la posibilidad de proporcionar indizadores en tipos que representan colecciones de elementos.
❌ EVITE usar propiedades indexadas con más de un parámetro.
Si el diseño requiere varios parámetros, reconsidere si la propiedad realmente representa un descriptor de acceso a una colección lógica. Si no es así, use los métodos en su lugar. Considere la posibilidad de empezar el nombre del método por Get
o Set
.
❌ EVITE los indizadores con tipos de parámetros distintos de System.Int32, System.Int64, System.String, System.Object o una enumeración.
Si el diseño requiere otros tipos de parámetros, vuelva a evaluar con firmeza si la API representa realmente un descriptor de acceso a una colección lógica. En caso contrario, use un método. Considere la posibilidad de empezar el nombre del método por Get
o Set
.
✔️ USE el nombre Item
de las propiedades indexadas, a menos que haya un nombre claramente mejor (p. ej., consulte la propiedad Chars[] en System.String
).
En C#, a los indizadores se les llama, de forma predeterminada, Elemento. IndexerNameAttribute se puede usar para personalizar este nombre.
❌ NO proporcione un indizador ni métodos que sean semánticamente equivalentes.
❌ NO proporcione más de una familia de indizadores sobrecargados en un tipo.
El compilador de C# aplica esto.
❌ NO use propiedades indexadas no predeterminadas.
El compilador de C# aplica esto.
Eventos de notificación de cambio de propiedad
A veces resulta útil proporcionar un evento que notifique al usuario los cambios en un valor de propiedad. Por ejemplo, System.Windows.Forms.Control
genera un evento TextChanged
después de que el valor de su propiedad Text
haya cambiado.
✔️ CONSIDERE la posibilidad de generar eventos de notificación de cambios cuando se modifiquen los valores de propiedad en las API de alto nivel (normalmente los componentes del diseñador).
Si hay un buen escenario para que un usuario sepa cuándo cambia una propiedad de un objeto, el objeto debe generar un evento de notificación de cambio para la propiedad.
Sin embargo, es improbable que merezca la pena la sobrecarga de generar tales eventos para las API de bajo nivel, como los tipos base o las colecciones. Por ejemplo, List<T> no generaría estos eventos cuando se agrega un nuevo elemento a la lista y cambia la propiedad Count
.
✔️ CONSIDERE la posibilidad de generar eventos de notificación de cambio cuando el valor de una propiedad cambie a través de fuerzas externas.
Si un valor de propiedad cambia a través de una fuerza externa (de forma distinta que llamando a los métodos en el objeto), los eventos de generación indican al desarrollador que el valor cambia y ha cambiado. Un buen ejemplo es la propiedad Text
de un control de cuadro de texto. Cuando el usuario escribe texto en un TextBox
, el valor de propiedad cambia automáticamente.
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.