이를 수행하는 전통적인 방법은에 Flags
속성 을 사용하는 것입니다 enum
.
[Flags]
public enum Names
{
None = 0,
Susan = 1,
Bob = 2,
Karen = 4
}
그런 다음 다음과 같이 특정 이름을 확인합니다.
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;
논리적 인 비트 조합은 기억하기 어려울 수 있으므로 FlagsHelper
클래스 *를 사용하여 자신의 삶을 더 쉽게 만듭니다 .
// 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));
}
}
이렇게하면 위 코드를 다음과 같이 다시 작성할 수 있습니다.
Names names = Names.Susan | Names.Bob;
bool susanIsIncluded = FlagsHelper.IsSet(names, Names.Susan);
bool karenIsIncluded = FlagsHelper.IsSet(names, Names.Karen);
Karen
다음을 수행하여 세트에 추가 할 수도 있습니다 .
FlagsHelper.Set(ref names, Names.Karen);
Susan
비슷한 방법으로 제거 할 수 있습니다 .
FlagsHelper.Unset(ref names, Names.Susan);
* Forges가 지적했듯이 IsSet
위 의 방법 과 동일한 방법이 .NET 4.0에 이미 존재합니다 Enum.HasFlag
. 그러나 Set
및 Unset
메서드에는 동등한 항목이없는 것 같습니다. 그래서 저는이 수업에 약간의 장점이 있다고 말하고 싶습니다.
참고 : 열거 형을 사용하는 것은 이 문제를 해결 하는 일반적인 방법 일뿐 입니다. 위의 모든 코드를 완전히 번역하여 대신 int를 사용할 수 있으며 잘 작동합니다.