Flags Attribute를 사용해보세요.

개발 중에는 때때로 하나의 enum 타입을 가지고 여러 value에 대해 분기해 처리해야 하는 경우가 생깁니다.

public enum EnumExample
{
    A,
    B,
    C
}

위와 같은 enum 타입이 있을 때, 상황이 항상 A이거나, B이거나, C이거나 셋 중 하나로 끝나면 매우 바람직하겠지만 대개 그렇지 않죠. A이거나, A와 B이거나, A와 C거나, B거나, ... 이런 상황이 자주 나옵니다.

그럼 어떻게 코딩해야 할까요? 아래처럼?

if (value == EnumExample.A)
{
    // ...
}
else if (value == EnumExample.A && value2 == EnumExample.B)
{
    // ...
}

말이 안 되죠.

System.FlagsAttribute Class

MSDN 문서에 따르면, 이 어트리뷰트가 적용된 enum은 비트 필드로 취급될 수 있다고 합니다. 즉, C언어 등에서 사용되는 비트 필드마냥 사용할 수 있게 된다는 뜻이죠. 다음 예시를 보세요.

[Flags]
public enum FlagsExample
{
    NONE = 0,
    A = 1,
    B = 2,
    C = 4,
    D = 8,
    E = 16,
}

위와 같이 선언된 enum은 각각의 값이 비트 필드로 취급됩니다. 즉 0은 0000 0000 0000 0000, A는 0000 0000 0000 0001, B는 0000 0000 0000 0010, C는 0000 0000 0000 0100, D는 0000 0000 0000 1000, E는 0000 0000 0001 0000과 같은 식으로 생각하시면 됩니다.

이렇게 되면 어떤 방식의 코딩이 가능해지냐? enum 값에 대한 비트 연산이 가능해집니다.


var abc = FlagsExample.A | FlagsExample.B | FlagsExample.C;
// abc = A, B, C

따라서 위와 같이 하나의 enum 변수에 여러 다른 값들을 구겨 넣을 수 있고, 마찬가지로 비교도 가능합니다. 비교는 System.Enum 클래스에서 제공하는 HasFlag 메서드를 사용하면 편합니다. 다만 HasFlag 메서드는 성능 이슈가 있으니 여건이 된다면 따로 구분하는 메서드를 만들어서 사용하는 것도 좋습니다.

if (abc.HasFlag(FlagsExample.A) && abc.HasFlag(FlagsExample.B))
{
    // 값에 A와 B가 모두 있을 때 실행될 코드
}

// OR (proper way)

if (abc.HasFlag(FlagsExample.A | FlagsExample.B))
{
    // 값에 A와 B가 모두 있을 때 실행될 코드
}

댓글

이 블로그의 인기 게시물

C# 남아도는 메모리에도 불구하고 OutOfMemoryException이 발생한다면?

USB를 뒤는 괜찮은데 앞에 꽂으면 인식이 힘들다?

MySQL 데이터 타입과 Java 데이터 타입 비교/매칭