Enumeratori: flags and extensions

di Matteo Casati, in .NET,

Può capitare di avere la necessità di utilizzare un'enumerazione come insieme di bit, ovvero come un elenco di elementi generato in modo combinato. Un esempio concreto di questo utilizzo potrebbe essere la gestione di una proprietà "Permission" che definisca quali operazioni (lettura, creazione, modifica, cancellazione, ecc.) è autorizzato a compiere un utente. Per poter gestire le diverse autorizzazioni con un unico enumeratore dobbiamo semplicemente aggiungere all'enumeratore l'attributo Flags ed avere l'accortezza di esplicitare i valori come potenze di 2 (1, 2, 4, 8, 16, 32, ecc. o nell'equivalente esadecimale 0x1, 0x2, 0x4, 0x8, 0x10, 0x20, ecc.) per consentire le operazioni bit per bit (AND, OR e XOR) evitando sovrapposizioni:

0: 0000
1: 0001
2: 0010
4: 0100
8: 1000
e così via.

Il nostro enumeratore sarà dunque:

[Flags] 
public enum Permission 
{ 
    None = 0x0, 
    Read = 0x1, 
    Execute = 0x2, 
    Create = 0x4, 
    Modify = 0x8, 
    Delete = 0x10, 
    Special = 0x20, 
    FullControl = Read | Execute | Create | Modify | Delete | Special 
}

Si noti la presenza di un valore predefinito - None = 0, che è sempre buona norma definire - e la dichiarazione di un valore combinato - FullControl pari all'insieme di tutte le autorizzazioni disponibili, combinate tramite OR; in modo analogo potremo definire le permission dei singoli utenti, ad esempio:

account.Permission = Permission.Read | Permission.Execute;

Saremo in grado di verificare se l'utente è autorizzato ad effettuare un determinato tipo di operazione mediante un confronto in AND:

bool canRead = (account.Permission & Permission.Read) != Permission.None;

Possiamo inoltre sfruttare i metodi di estensioni del Framework (3.5 o superiore, necessitano un riferimento a System.Core.dll) per centralizzare questo confronto ed esporlo direttamente attraverso l'enumeratore:

public static class PermissionExtensions 
{ 
    public static bool HasPermission(this Permission permission, Permission permissionToCheck) 
    { 
        return (permission & permissionToCheck) != Permission.None; 
    } 
}

Così da avere:

bool canRead = account.Permission.HasPermission(Permission.Read);

HTH

Commenti

Visualizza/aggiungi commenti

| Condividi su: Twitter, Facebook, LinkedIn

Per inserire un commento, devi avere un account.

Fai il login e torna a questa pagina, oppure registrati alla nostra community.

Nella stessa categoria
I più letti del mese