2012-11-19 7 views
5

ho creato un metodo di estensione in quanto tale ..Controllare se esclusivamente solo questi flag impostati nella enumerazione

public static bool AllFlagsSet<T>(this T input, params T[] values) where T : struct, IConvertible 
{ 
    bool allSet = true; 
    int enumVal = input.ToInt32(null); 

    foreach (T itm in values) 
    { 
     int val = itm.ToInt32(null); 
     if (!((enumVal & val) == val)) 
     { 
      allSet = false; 
      break; 
     } 
    } 

    return allSet; 
} 

Quali grandi opere per le finalità di cui avevo bisogno, ma ora ho un obbligo di creare un metodo con il stessa firma che controlla se sono stati impostati solo questi valori.

Fondamentalmente qualcosa del genere.

public static bool OnlyTheseFlagsSet<T>(this T input, params T[] values) where T : struct, IConvertible 
{ 
} 

L'unico modo che posso pensare di fare questo è quello di ottenere tutti i valori di enumerazione disponibili controllo che sono impostati e confermando che solo i due non siano state.

C'è un altro modo per risolvere questo problema utilizzando una sorta di operazione bit a bit?

+0

È questo un compito ?? E perché il vincolo di T è una struct e non un enum ?? – LightStriker

+0

lol, beh, questo è imbarazzante. No, solo non avere ancora una solida conoscenza delle operazioni bit a bit ... Questo è un vero requisito –

+0

Provare a vincolarlo a Enum e vedere cosa succede. ;-p –

risposta

5

Fare "o" su tutti i flag richiesti e confrontare con l'input - dovrebbe essere uguale. Simile a seguire, con il ciclo corretto per calcolare il valore a sinistra:

var onlyTheseFlagsSet = (value[0] | value[1]) == input; 
0

mi manca qualcosa o non poteva semplicemente somma params [] valori T e verificare se l'ingresso è uguale al risultato?
Se si desidera solo quei flag e nessun altro, l'input deve essere uguale alla somma di tali flag.

+1

Somma come '+' può essere pericoloso poiché i valori Enum anche per i tipi di flag non devono necessariamente escludersi a vicenda: uno deve usare o '|' per combinare i flag correttamente. –

1

Questo capovolge il bit di ciascun valore di input. Se sono impostati solo quelli, il valore risultante sarà zero. Altrimenti, invertirà i bit a 1 se il valore non è impostato su input, che lascerà il valore diverso da zero.

public static bool OnlyTheseFlagsSet<T>(this T input, params T[] values) where T : struct, IConvertible 
{ 
    int enumVal = input.ToInt32(null); 

    foreach (T itm in values) 
    { 
     int val = itm.ToInt32(null); 
     enumVal = enumVal^val;     
    } 

    return (enumVal == 0); 
} 
+1

+1. Mi piace l'approccio '|', ma anche questo è interessante. Nota a margine - si prega di evitare shrtng nms f vrbls come 'itm' invece di' item'. –

+0

Anche l'approccio '|' mi piace di più. D'accordo sui nomi variabili, stavo solo mantenendo lo stile dell'autore originale. –

+0

Nota a margine: appena notato - il tuo codice si basa su valori che si escludono a vicenda ... non è necessario vero anche per i valori di Enum contrassegnati come flag. –

0

Supponendo che è possibile convertire il vostro input ad un enum:

foreach(MyFlags flag in values) 
    if (!input.HasFlag(flag)) 
     return false; 

return true; 

Sì, sono pigro in quel modo.

+0

Penso che OP vuole anche assicurarsi che non siano impostati altri flag ... in attesa dei commenti dell'OP ... –

2

Esclusività requisito significa che

input = values[0] | values[1] | ... | values[values.Length - 1]

Così, qui è la vostra applicazione:

return input.ToInt32(null) == values.Aggregate(0, 
     (total, next) => total | next.ToInt32(null)); 
+0

+1. Quel '.ToInt32 (null)' sembra strano, ma funziona comunque! –

Problemi correlati