2011-09-19 8 views
30

Mi chiedo un modo generico per impostare tutti i bit del flag enum su 1. Mi piacerebbe avere uno enum che restituisce tutti i confronti, indipendentemente dalle altre enumerazioni.Come impostare tutti i bit di enum flag

E questo codice funziona;

[Flags] 
public enum SomeRightEnum : uint 
{ 
    CanDoNothing = 0, 
    CanDoSomething = 1 << 0, 
    CanDoSomethingElse = 1 << 1, 
    CanDoYetAnotherThing = 1 << 2, 
    ... 
    DoEverything = 0xFFFFFFFF 
} 

Ma al codice di cui sopra in quanto è uint abbiamo impostato il numero di s "F", che non avrebbe funzionato se fosse int.

Così mi sarà utile un metodo generico per impostare tutti i bit di enum bandiera a 1, indipendentemente dal tipo di dati (i nt, int64, uint ecc)

+1

Hmmm. L'intento delle enumerazioni è quello di descrivere opzioni mutuamente esclusive. Sembra che tu li stia usando come abbreviazione di un mucchio di maschere di bit. –

+1

@AFgone Stai utilizzando l'attributo [Flags] sull'enum giusto? –

+1

@Oli L'attributo [Flags] sull'enumerazione è progettato per questo scopo. –

risposta

47

più semplice è probabilmente:

enum Foo 
{ 
    blah = 1, 
    .... 
    all = ~0 
} 

Per enum basato unsigned:

enum Foo : uint 
{ 
    blah = 1, 
    .... 
    all = ~0u; 
} 
+0

quando provo questo dice "Il valore costante '-1' non può essere convertito in un 'uint'" – AFgone

+1

Just cast quindi, ad esempio 'deselezionata ((uint) ~ 0)' – leppie

+0

molte grazie questa è la cosa che stavo cercando – AFgone

3
internal static class Program 
{ 
    private static void Main() 
    { 
     Console.WriteLine(Foo.Everything.HasFlag(Foo.None)); // False 
     Console.WriteLine(Foo.Everything.HasFlag(Foo.Baz)); // True 
     Console.WriteLine(Foo.Everything.HasFlag(Foo.Hello)); // True 
    } 
} 

[Flags] 
public enum Foo : uint 
{ 
    None = 1 << 0, 
    Bar = 1 << 1, 
    Baz = 1 << 2, 
    Qux = 1 << 3, 
    Hello = 1 << 4, 
    World = 1 << 5, 
    Everything = Bar | Baz | Qux | Hello | World 
} 

era questo quello che volevi?

+0

ma questo non è indipendentemente dalle altre enumerazioni, quando modifico o rimuovo enumerazioni devo cambiare anche "Tutto" – AFgone

5

Nel caso in cui qualcuno sta chiedendo: avevo bisogno di fare la stessa costruzione di un enumconverter Bindable per WPF.
Dal momento che non so cosa significano i valori in Reflection, avevo bisogno di cambiare manualmente i valori (collegandoli a una casella di controllo)
C'è un problema nell'impostare il valore di un'enumerazione contrassegnata su -1 per impostare tutti i bit.
Se lo si imposta su -1 e si rimuovono tutti i valori, non si ottiene 0 perché tutti i bit non utilizzati non vengono contrassegnati.
Questo è wat ha funzionato meglio per la mia situazione.

SomeRightEnum someRightEnum = SomeRightEnum.CanDoNothing; 
Type enumType = someRightEnum.GetType(); 
int newValue = 0; 
var enumValues = Enum.GetValues(enumType).Cast<int>().Where(e => e == 1 || e % 2 == 0); 
foreach (var value in enumValues) 
{ 
    newValue |= value; 
} 
Console.WriteLine(newValue); 

Oppure, se si vuole un metodo di estensione:

public static class FlagExtensions 
{ 
    public static TEnum AllFlags<TEnum>(this TEnum @enum) 
     where TEnum : struct 
    { 
     Type enumType = typeof(TEnum); 
     long newValue = 0; 
     var enumValues = Enum.GetValues(enumType); 
     foreach (var value in enumValues) 
     { 
      long v = (long)Convert.ChangeType(value, TypeCode.Int64); 
      if(v == 1 || v % 2 == 0) 
      { 
       newValue |= v; 
      } 
     } 
     return (TEnum)Enum.ToObject(enumType , newValue); 
    } 
} 
+0

ne fanno un metodo di estensione chiamato 'AllFlags' che estende la classe di sistema' enum'. allora potrebbe essere usato ordinatamente enum.AllFlags (typeof (MyEnum)) 'no? –

+0

@ v.oddou Ho aggiornato la mia risposta con un'estensione generica che restituisce il valore (immutabile). Ho anche rimosso un bug per omettere i valori non di flag. – Silvermind

18
[Flags] 
public enum MyEnum 
{ 
    None = 0, 
    First = 1 << 0, 
    Second = 1 << 1, 
    Third = 1 << 2, 
    Fourth = 1 << 3, 
    All = ~(-1 << 4) 
} 
+0

Mi piace questa opzione anche meglio della mia solita opzione '-1'. Stavo usando un enum per tenere traccia di quali attività sono state richieste e rimuovere il flag quando l'attività è stata completata. Il mio piano era quindi di usare il risultato come codice di uscita. Quindi questo aiuta a mantenere l'enum dei compiti. – Schmalls

+1

Preferisco 'Tutto = ~ (~ 0 << 4)' perché è un po 'più chiaro. Non tutti sanno che '-1' è tutto' 1's. –

+0

'Nessuna' non deve essere' -1'?! – akhansari

Problemi correlati