La manière traditionnelle de procéder consiste à utiliser l' Flags
attribut sur un enum
:
[Flags]
public enum Names
{
None = 0,
Susan = 1,
Bob = 2,
Karen = 4
}
Ensuite, vous vérifieriez un nom particulier comme suit:
Names names = Names.Susan | Names.Bob;
// evaluates to true
bool susanIsIncluded = (names & Names.Susan) != Names.None;
// evaluates to false
bool karenIsIncluded = (names & Names.Karen) != Names.None;
Les combinaisons logiques au niveau du bit peuvent être difficiles à retenir, donc je me simplifie la vie avec une FlagsHelper
classe *:
// The casts to object in the below code are an unfortunate necessity due to
// C#'s restriction against a where T : Enum constraint. (There are ways around
// this, but they're outside the scope of this simple illustration.)
public static class FlagsHelper
{
public static bool IsSet<T>(T flags, T flag) where T : struct
{
int flagsValue = (int)(object)flags;
int flagValue = (int)(object)flag;
return (flagsValue & flagValue) != 0;
}
public static void Set<T>(ref T flags, T flag) where T : struct
{
int flagsValue = (int)(object)flags;
int flagValue = (int)(object)flag;
flags = (T)(object)(flagsValue | flagValue);
}
public static void Unset<T>(ref T flags, T flag) where T : struct
{
int flagsValue = (int)(object)flags;
int flagValue = (int)(object)flag;
flags = (T)(object)(flagsValue & (~flagValue));
}
}
Cela me permettrait de réécrire le code ci-dessus comme suit:
Names names = Names.Susan | Names.Bob;
bool susanIsIncluded = FlagsHelper.IsSet(names, Names.Susan);
bool karenIsIncluded = FlagsHelper.IsSet(names, Names.Karen);
Notez que je pourrais également ajouter Karen
à l'ensemble en faisant ceci:
FlagsHelper.Set(ref names, Names.Karen);
Et je pourrais supprimer Susan
de la même manière:
FlagsHelper.Unset(ref names, Names.Susan);
* Comme Porges a souligné, un équivalent de la IsSet
méthode ci - dessus existe déjà dans .NET 4.0: Enum.HasFlag
. Les Set
et Unset
méthodes ne semblent pas avoir équivalents, cependant; alors je dirais toujours que cette classe a du mérite.
Remarque: l'utilisation d'énumérations n'est que la manière conventionnelle de résoudre ce problème. Vous pouvez totalement traduire tout le code ci-dessus pour utiliser ints à la place et cela fonctionnera tout aussi bien.