Diseño de enumeraciones

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.

Las enumeraciones son un tipo de valor especial. Hay dos tipos de enumeraciones: enumeraciones simples y enumeraciones de marca.

Las enumeraciones simples representan conjuntos pequeños y cerrados de opciones. Un ejemplo típico de enumeración simple es un conjunto de colores.

Las enumeraciones de marca están diseñadas para admitir operaciones bit a bit en los valores de enumeración. Un ejemplo típico de enumeración de marca es una lista de opciones.

✔️ USE una enumeración para escribir de forma segura parámetros, propiedades y valores devueltos que representan conjuntos de valores.

✔️ AUMENTE el uso de enumeraciones en detrimento de las constantes estáticas.

❌ NO use una enumeración para conjuntos abiertos (como la versión del sistema operativo, los nombres de sus amigos, etc.).

❌ NO proporcione valores de enumeración reservados que estén pensados para usos futuros.

Siempre le queda la opción de agregar valores a la enumeración existente en una fase posterior. Consulte Agregar valores a las enumeraciones para obtener más información sobre cómo agregar valores a las enumeraciones. Los valores reservados simplemente contaminan el conjunto de valores reales y tienden a provocar errores de usuario.

❌ EVITE exponer públicamente las enumeraciones con un solo valor.

Una práctica habitual para garantizar la extensibilidad futura de las API de C es agregar parámetros reservados a firmas de método. Estos parámetros reservados se pueden expresar como enumeraciones con un único valor predeterminado. Esto no debe realizarse en las API administradas. La sobrecarga de métodos permite agregar parámetros en futuras versiones.

❌ NO incluya valores de sentinel en las enumeraciones.

Aunque a veces son útiles para los desarrolladores del marco, los valores de sentinel son confusos para los usuarios del marco. Se usan más para realizar un seguimiento del estado de la enumeración que para ser uno de los valores del conjunto representado por la enumeración.

✔️ PROPORCIONE un valor de cero en las enumeraciones simples.

Considere la posibilidad de llamar al valor algo como "None" (Ninguno). Si este valor no es adecuado para esta enumeración concreta, se debe asignar el valor subyacente de cero al valor predeterminado más común de la enumeración.

✔️ CONSIDERE la posibilidad de usar Int32 (el valor predeterminado en la mayoría de los lenguajes de programación) como el tipo subyacente de una enumeración, a menos que se cumpla alguna de las siguientes afirmaciones:

  • La enumeración es una enumeración de marca y usted tiene más de 32 marcas, o espera tener más en el futuro.

  • El tipo subyacente debe ser diferente de Int32 para facilitar la interoperabilidad con código no administrado que espera enumeraciones de distintos tamaños.

  • Un tipo subyacente más pequeño daría como resultado un ahorro sustancial en el espacio. Si espera que la enumeración se use principalmente como argumento para el flujo de control, el tamaño importa poco. El ahorro de tamaño puede ser significativo si:

    • Se espera que la enumeración se use como un campo en una estructura o clase con instancias muy frecuentes.

    • Se espera que los usuarios creen grandes matrices o colecciones de las instancias de enumeración.

    • Se espera que se serialicen un gran número de instancias de la enumeración.

Para el uso en memoria, tenga en cuenta que los objetos administrados siempre están alineados con DWORD, por lo que, en la práctica, necesita varias enumeraciones u otras estructuras pequeñas en una instancia con las que empaquetar una enumeración más pequeña y así obtener una diferencia relevante, ya que el tamaño total de la instancia siempre se va a redondear a DWORD.

✔️ ASIGNE nombres que tengan sustantivos en plural o sintagmas nominales para las enumeraciones de marca. Para las enumeraciones simples, los nombres deben tener sustantivos en singular o sintagmas nominales.

❌ NO amplíe directamente System.Enum.

System.Enum es un tipo especial utilizado por CLR para crear enumeraciones definidas por el usuario. La mayoría de los lenguajes de programación proporcionan un elemento de programación que da acceso a esta funcionalidad. Por ejemplo, en C# la palabra clave enum se usa para definir una enumeración.

Diseño de enumeraciones de marca

✔️ APLIQUE System.FlagsAttribute a las enumeraciones de marca. No aplique este atributo a las enumeraciones simples.

✔️ USE potencias de dos para los valores de las enumeraciones de marca. Así, se podrán combinar libremente mediante la operación OR bit a bit.

✔️ CONSIDERE la posibilidad de proporcionar valores de enumeración especiales para las combinaciones de marcas que se usan habitualmente.

Las operaciones bit a bit son un concepto avanzado y no deben utilizarse para tareas sencillas. ReadWrite es un ejemplo de este tipo de valores especiales.

❌ EVITE crear enumeraciones de marca en las que determinadas combinaciones de valores no sean válidas.

❌ EVITE el uso de valores de cero en las enumeraciones de marca, a menos que el valor represente que "todas las marcas están borradas" y tenga un nombre correcto, según lo indicado por la siguiente guía.

✔️ ASIGNE este nombre al valor de cero de las enumeraciones de marca: None. Para una enumeración de marca, el valor siempre debe significar "todas las marcas están borradas".

Agregar valor a las enumeraciones

Es muy habitual descubrir que necesita agregar valores a una enumeración después de que ya la haya enviado. Hay un posible problema de compatibilidad entre aplicaciones cuando se devuelve el valor recién agregado de una API existente, ya que puede que las aplicaciones mal escritas no controlen correctamente el nuevo valor.

✔️ CONSIDERE la posibilidad de agregar valores a las enumeraciones, a pesar del pequeño riesgo en la compatibilidad.

Si tiene datos reales sobre las incompatibilidades entre aplicaciones provocadas por valores agregados a una enumeración, considere la posibilidad de agregar una nueva API que devuelva los valores nuevos y antiguos, y deje de usar la API antigua, que a priori seguirá devolviendo solo los valores antiguos. Esto garantizará que las aplicaciones existentes sigan siendo compatibles.

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.

Vea también