Enum은 상수를 의미있는 단어들로 표현할 수 있게 해준다.
public enum Direction
{
Up // 0
Down // 1
Left // 2
Right // 3
}
위는 enum이 존재하는 의미를 잘 알 수 있는 한 예시이다.
string / bool 타입 모두 Direction을 표현하기에는 애매하거나 비효율적이다.
int 타입으로 표현했을 때, (0, 1, 2, 3) 각각이 어떤 방향을 나타내는지 알기 힘들다.
따라서 의미 있는 단어들로 표현할 수 있게끔 enum을 이용한다.
앞서 말했던 것처럼 enum은 상수를 표현한 것이다. 따라서 enum 타입을 int 타입으로 casting 할 수 있다.
위의 예시처럼 따로 enum을 상수로 정의하지 않으면, 위(UP)를 0으로 정의하고, 아래로 1씩 증가하여 정의된다.
public enum Direction
{
Up = 2 // 2
Down // 3
Left = 7 // 7
Right // 8
}
위의 예시처럼 enum을 상수로 정의할 수도 있다.
Enum은 정수형을 기반으로 작동하므로 AND / OR / XOR / NOT 등 비트 연산을 할 수 있다.
아래는 AND / OR 비트 연산의 예시이다.
public enum Direction
{
Up // 0
Down // 1
Left // 2
Right // 3
}
Direction UpRight = Direction.Up | Direction.Right; // OR
Console.WriteLine(Upright); // Output: 3
if ((UpRight & Direction.Up) == Direction.Up) // AND
{
Console.WriteLine("Up");
}
하지만, 위의 방식으로 비트 연산을 이용할 경우, Upright의 출력이 3이 된다. 이는 비트 연산을 표현하기에 적합하지 않다.
따라서 아래의 Attribute를 이용한다.
Flags 특성을 enum에 추가하면, 이를 비트 플래그로 사용할 수 있다.
[Flags]
public enum Direction
{
Up // 0b00_0000
Down // 0b00_0001
Left // 0b00_0010
Right // 0b00_0011
}
Direction UpRight = Direction.Up | Direction.Right; // OR
Console.WriteLine(Upright); // Output: Up, Right
이 경우 출력이 Up, Right로 비트 플래그의 의도를 잘 전달할 수 있다.
GetName은 특정 enum 값에 대한 이름을 반환한다.
[Flags]
public enum Direction
{
Up // 0b00_0000
Down // 0b00_0001
Left // 0b00_0010
Right // 0b00_0011
}
string name = Enum.GetName(typeof(Direction), 1);
Console.WriteLine(name); // Output: Down
값에 대한 이름이 존재하지 않을 경우 null을 반환한다.
GetValues는 enum에 정의된 모든 값을 배열 형태로 반환한다.
[Flags]
public enum Direction
{
Up // 0b00_0000
Down // 0b00_0001
Left // 0b00_0010
Right // 0b00_0011
}
Array values = Enum.GetValues(typeof(Direction));
foreach (var value in values)
Console.WriteLine($"{value} = {(int)value}");
cf) GetNames는 enum에 정의된 모든 이름을 문자열 배열(String[])으로 변환한다.
HasFlag는 Enum에서 특정 값(플래그)이 설정되어 있는지를 확인하는 데 사용되는 method이다.
[Flags]
public enum Direction
{
Up // 0b00_0000
Down // 0b00_0001
Left // 0b00_0010
Right // 0b00_0011
}
Direction UpRight = Direction.Up | Direction.Right;
Console.WriteLine(UpRight.HasFlag(Direction.Up); // Output: True
Console.WriteLine(UpRight.HasFlag(Direction.Down); // Output: False
HasFlag는 내부적으로 비트 AND 연산을 이용하여 특정 플래그가 있는지를 확인한다.
내부적으로 boxing을 이용하기 때문에, 빈번하게 호출하면 성능에 영향을 미칠 수 있고, 이 경우 직접 AND 연산을 이용하는게 빠르다.
저도 개발하면서 배우는 중이라 내용에 문제가 있을 수 있어요!
혹시라도 잘못된 내용이 있다면 말해주세요.
확인 후 고치도록 하겠습니다.
읽어주셔서 감사합니다.