come posso attivare un enum che ha l'attributo flags impostato (o più precisamente viene usato per le operazioni bit)?Accendi Enum (con attributo Flags) senza dichiarare ogni combinazione possibile?
Voglio essere in grado di colpire tutti i casi in un interruttore che corrisponde ai valori dichiarati.
Il problema è che se ho il seguente enum
[Flags()]public enum CheckType
{
Form = 1,
QueryString = 2,
TempData = 4,
}
e voglio utilizzare un interruttore come questo
switch(theCheckType)
{
case CheckType.Form:
DoSomething(/*Some type of collection is passed */);
break;
case CheckType.QueryString:
DoSomethingElse(/*Some other type of collection is passed */);
break;
case CheckType.TempData
DoWhatever(/*Some different type of collection is passed */);
break;
}
Se "theCheckType" è impostato su entrambi CheckType.Form | CheckType.TempData Voglio che colpisca entrambi i casi. Ovviamente non verrà colpito nel mio esempio a causa dell'interruzione, ma a parte questo fallisce anche perché CheckType.Form non è uguale a CheckType.Form | CheckType.TempData
L'unica soluzione quindi, come posso vedere, è creare un caso per ogni possibile combinazione dei valori enumerati?
Qualcosa di simile
case CheckType.Form | CheckType.TempData:
DoSomething(/*Some type of collection is passed */);
DoWhatever(/*Some different type of collection is passed */);
break;
case CheckType.Form | CheckType.TempData | CheckType.QueryString:
DoSomething(/*Some type of collection is passed */);
DoSomethingElse(/*Some other type of collection is passed */);
break;
... and so on...
ma che in realtà è neanche molto desiderata (come sarà rapidamente crescerà molto grande)
In questo momento ho 3 Se le condizioni di destra dopo la vicenda, invece
Qualcosa di simile
if ((_CheckType & CheckType.Form) != 0)
{
DoSomething(/*Some type of collection is passed */);
}
if ((_CheckType & CheckType.TempData) != 0)
{
DoWhatever(/*Some type of collection is passed */);
}
....
Ma questo significa anche che se ho un enum wi i 20 valori devono passare attraverso 20 Se le condizioni ogni volta invece di "saltare" solo al "caso"/s necessario come quando si usa un interruttore.
C'è qualche soluzione magica per risolvere questo problema?
Ho pensato alla possibilità di eseguire il loop dei valori dichiarati e quindi utilizzare lo switch, quindi avrebbe colpito l'interruttore solo per ogni valore dichiarato, ma non so come funzionerà e se il rendimento è vice una buona idea (rispetto a molte di se)?
Esiste un modo semplice per eseguire il ciclo di tutti i valori enumerati dichiarati?
Posso solo utilizzare ToString() e dividere per "," e quindi scorrere l'array e analizzare ogni singola stringa.
UPDATE:
vedo che non ho fatto un lavoro abbastanza buono per spiegare. Il mio esempio è semplice (ho cercato di semplificare il mio scenario).
Lo uso per un ActionMethodSelectorAttribute in Asp.net MVC per determinare se un metodo deve essere disponibile quando si risolve l'url/route.
lo faccio dichiarando qualcosa di simile sul metodo
[ActionSelectorKeyCondition(CheckType.Form | CheckType.TempData, "SomeKey")]
public ActionResult Index()
{
return View();
}
Ciò significherebbe che dovrebbe controllare se il modulo o TempData hanno una chiave, come specificato per il metodo sia disponibile.
I metodi che chiamerà (doSomething(), doSomethingElse() e doWhatever() nell'esempio precedente) avranno in realtà bool come valore di ritorno e verranno chiamati con un parametro (raccolte diverse che non condividono un interfaccia che può essere utilizzata - vedi il mio codice di esempio nel link sottostante ecc.).
Per spera dare una migliore idea di quello che sto facendo ho incollato un semplice esempio di quello che sto facendo su pastebin - può essere trovato qui http://pastebin.com/m478cc2b8
Grazie per la risposta. È praticamente la soluzione di Lukes che utilizza lo switch al posto della mappatura del dizionario. Questa sembra essere la soluzione migliore anche se ho davvero sperato che fosse possibile in qualche modo solo il ciclo dei valori in "theCheckType" invece di fare il ciclo dell'intera enumerazione, poiché non c'è davvero alcun motivo per controllare tutti i valori enum, solo il quelli impostati in "theCheckType". Ma immagino che non sia possibile. – MartinF
Non vedo la somiglianza con la risposta di Luca; Penso che il mio sia significativamente più semplice.Per come la vedo io, devi controllare "theCheckType" contro l'enum o controllare l'enum contro "theCheckType". In entrambi i casi è necessario verificare tutti i valori possibili. Se dichiari il tuo enum a lungo (Int64) puoi ovviamente avere un massimo di 64 valori, quindi non c'è bisogno di preoccuparsi delle prestazioni in un ciclo così breve. –
Dai un'occhiata a questo: http://stackoverflow.com/questions/1060760/what-to-do-when-mas-mask-flags-enum-gets-too-large –