El atributo Flag en C#

En el Post de hoy voy a hacer mención a una funcionalidad de C# que sinceramente, a mi se me había olvidado, la ví por primera vez en mi primer trabajo allá por 2014/2015 y no la había vuelto a ver hasta hace un par de semanas. 

 

En ese momento, me saltó la chispa y dije, porqué no hacer un post sobre Flags en C#.

 

 

 

1 - Qué es el atributo flag de C# y para qué sirve? 

 

Bueno el atributo flag es un atributo que se le pone a un enum para convertirlo en bits, eso quiere decir, que, cada uno de los valores representa un valor de bits. 

 

En otras palabras, que cuando utilizamos el atributo en un enum, este se nos traduce a binario: 

[Flags]
public enum TestFlags
{
    FirstValue = 00,
    SecondValue = 01,
    ThirdValue = 10
}

 

 

En este ejemplo, los valores serían equivalentes a:

FirstValue = 00000,
SecondValue = 00001,
ThirdValue = 00010

 

Nota: técnicamente podemos usar Binary literals 0b0000, pero al final es lo mismo.

 

O lo que es lo mismo en un valor numérico:

 

FirstValue = 0,
SecondValue = 1,
ThirdValue = 2

 

 

Y claro, visto esto, te puedes preguntar, pero ¿ para qué sirve realmente, o cual es la utilidad real del atributo flag? 

 

 

 

2  - Caso de uso real del atributo Flag de c#

 

La forma más sencilla de ver como funciona es con un caso de uso real, que es el caso particular donde yo vi las flags hace 8 años, los permisos de usuario. Vamos a suponer que tenemos los siguientes permisos para cierta funcionalidad: 

 

  • None
  • View
  • Create
  • Edit
  • Delete

 

Tenemos una web, donde, tenemos diferentes acciones. Técnicamente no hace falta poner el “none” pero por claridad, durante la explicación, en mi opinión, se ve más fácil. 

 

Estas acciones las vamos a pasar a nuestro enum y les vamos a asignar un valor, como hemos visto antes lo podemos asignar utilizando el valor del entero:

 

[Flags]
public enum Permissions
{
    //None = 0, //0b0000
    View = 1, //0b0001
    Create = 2, //0b0010
    Edit = 4, //0b0100
    Delete = 8 //0b1000
}

 

Estamos acostumbrados a que con los enum en C# solo se puede tener un valor asignado, si continuamos con este ejemplo, tendremos permisos de editar, y tenemos asignado el valor 4. Esto quiere decir que podemos crear y ver? 

 

Bueno pues claramente si tenemos un if que hace if(user.permissions  == Permissions.Create) nos va  fallar, porque tenemos un 4; 

 

Una forma de arreglar esto, sería comprobando mayor y menor, pero entonces alguien que pueda borrar puede crear y editar y quizá tu lógica no espere eso.

 

Aquí es donde viene el verdadero motivo por el que el atributo flag es útil. 

Estamos trabajando con binario por lo que tenemos bits que nos dicen si algo esta habilitado o no. Por ejemplo, si podemos ver, editar y crear, tendremos las 3 primeras opciones, que suman 7, y 7 en binario es 0b0111 como puedes ver son los bits, individuales de cada una de las opciones, y estos, no tienen conflicto entre ellos. 

 

Si por ejemplo, podemos ver y borrar, pero no editar ni crear, tendremos el valor de 0b1001 que es 9.

 

Ahora que tenemos esto claro, solo nos queda entender cómo asignamos los valores, lo cual lo hacemos con el bitwise operator:

 

Permissions userPermissions = Permissions.View | Permissions.Delete;

 

Y luego comparamos con el método .HasFlag(...)

 

if (userPermissions.HasFlag(Permissions.View))
{
    //Then we can see the page;
}

if (userPermissions.HasFlag(Permissions.Create))
{
    //then the user can see the create button
}

 

 

Y como podemos ver, funciona a la perfección. En mi opinión, es una de las mejores, si no la mejor de tratar permisos, porque nos permite incluir mucha variedad de permisos combinados de una forma muy sencilla. 

 

 

Antes de acabar, si hacemos .ToString() nos lo devuelve las flags que tenemos activadas como un string con los valores separados por comas. Si hacemos un cast a int, nos da el valor. Cuando leemos de la base de datos pues tenemos que saber cómo hemos guardado, para hacer el mapeo de vuelta.

 

 

 


Uso del bloqueador de anuncios adblock

Hola!

Primero de todo bienvenido a la web de NetMentor donde podrás aprender programación en C# y .NET desde un nivel de principiante hasta más avanzado.


Yo entiendo que utilices un bloqueador de anuncios como AdBlock, Ublock o el propio navegador Brave. Pero te tengo que pedir por favor que desactives el bloqueador para esta web.


Intento personalmente no poner mucha publicidad, la justa para pagar el servidor y por supuesto que no sea intrusiva; Si pese a ello piensas que es intrusiva siempre me puedes escribir por privado o por Twitter a @NetMentorTW.


Si ya lo has desactivado, por favor recarga la página.


Un saludo y muchas gracias por tu colaboración

© copyright 2024 NetMentor | Todos los derechos reservados | RSS Feed

Buy me a coffee Invitame a un café