Saltar al contenido

Artículos, tutoriales, trucos, curiosidades, reflexiones y links sobre programación web ASP.NET Core, MVC, Blazor, SignalR, Entity Framework, C#, Azure, Javascript... y lo que venga ;)

17 años online

el blog de José M. Aguilar

Inicio El autor Contactar

Artículos, tutoriales, trucos, curiosidades, reflexiones y links sobre programación web
ASP.NET Core, MVC, Blazor, SignalR, Entity Framework, C#, Azure, Javascript...

¡Microsoft MVP!
viernes, 14 de septiembre de 2007
De todos es sabido que las enumeraciones son un tipo valor, y se representan internamente como Byte, Int32 u otros tipos primitivos de la plataforma, lo que hace imposible la asignación de valores como null, concebido para los tipos referencia.

Así, en el siguiente ejemplo en C#:

Estado estado1 = Estado.Correcto;
Estado estado2 = null;

La segunda línea provoca el error en compilación "No se puede convertir null en 'ConsoleApplication1.Program.Estado' porque es un tipo de valor". Lógico, es igual que que si intentáramos asignar el maldito valor nulo a un integer.

Esto puede causar ligeras molestias para la gestión de valores "indeterminados", puesto que estaríamos obligados, por ejemplo, a utilizar otro miembro de la enumeración para representar este valor, como en el siguiente código en Visual Basic .Net:

Public Enum Estado
Indeterminado = 0
Correcto = 1
Incorrecto = 2
End Enum

Sin embargo, hay ocasiones en la que resulta más interesante poder disponer del valor nulo como una opción para las variables del tipo de nuestra enumeración. Por ejemplo, si estamos desarrollando componentes que leen de una base de datos donde la indeterminación se representa por un nulo, sería más natural poder trasladar esta particularidad al modelo de objetos.

Y para esto inventaros los tipos anulables, de los que ya publiqué un post hace tiempo (Nullable Types, o cómo convivir con los nulos). Dado que las enumeraciones son tipos valor, nada impide crear tipos anulables de enumeraciones:

' VB.NET
Dim estado1 As Nullable(Of Estado)
Dim estado2 As Nullable(Of Estado)
estado1 = Estado.Correcto
estado2 = Nothing

// C#
Estado? estado1 = Estado.Correcto;
Estado? estado2 = null;

 

2 Comentarios:

Anónimo dijo...

buenas jose! }:)

No entiendo por que querrias usar un Nullable type en vez de añadir un primer valor al enumerado (el "Indeterminado" en tu ejemplo) que lo represente. Ademas, si dejamos la variable de tipo enumerado sin inicializar, es ese primer valor el que se usara por defecto (con lo que tenemos el mismo efecto que un null)

Ves alguna ventaja/inconveniente para decidir usar Nullable?

josé M. Aguilar dijo...

Hola, Ricardo, ante todo gracias por comentar.

Mira, así al vuelo, se me ocurren algunos casos donde yo optaría por utilizar nullables. De todas formas, como en casi todo en este mundo, aquí caben las preferencias personales, y en todos los casos se podría tirar por utilizar un elemento de la enumeración para indicar los valores especiales.

Por ejemplo, veo más natural representar un valor indeterminado como un nulo que como un valor de la propia enumeración siempre, claro está, que la indeterminación no tenga un valor semántico propio. Me explico.

En mi opinión sería es algo así como "contaminar" los valores posibles. Imagina una enumeración para representar el estado de un interruptor; podría ser "on" u "off", nunca indeterminado. Por eso, en mi opinión, sería poco natural añadir la indeterminación a los posibles valores del interruptor. El hecho de no conocer el estado de un interruptor no indica un posible estado nuevo.

Otro ejemplo podría ser si estuviéramos modelando clases para representar entidades (por ejemplo almacenadas en una BDD) en cuyos campos ya se usan valores nulos. También en este caso vería más natural la aplicación de nullables, digamos que sería un mapeo más directo entre el modelo de persistencia y el de clases.

Por último, otro caso. Imagina un método de acceso a datos que devuelva una serie de interruptores que cumplan los criterios especificados, con la siguiente signatura:

Interruptor[]
ObtenerInterruptores(par1, par2..., Estado estado)


El uso de tipos anulables en el parámetro "estado" (es decir, declararlo como "Estado? estado") podría ayudarnos a indicar cuándo queremos ignorar este parámetro, puesto que podríamos usar el valor null. Obviamente, podría sustituirse por una sobrecarga del método, pero a veces esto no es sencillo o resultaría muy trabajoso.

Como verás, desde mi punto de vista, pueden existir muchos escenarios donde tiene sentido el uso de anulables con las enumeraciones. Ahora bien, la decisión es más filosófica que otra cosa, y muchas veces será cuestión de gustos personales.