CodeGym /행동 /C# SELF /C#의 열거형(enum): 편리한 이름이 붙은 상수들

C#의 열거형(enum): 편리한 이름이 붙은 상수들

C# SELF
레벨 10 , 레슨 4
사용 가능

1. 소개

프로그래밍하다 보면 미리 정해진, 한정된 선택지 리스트를 다루는 일이 진짜 많아. 예를 들면: 요일, 신호등 색깔, 게임 난이도, 주문 상태 같은 거. 이런 각각의 선택지는 보통 고정된 값으로 표현되지. 오늘의 주제인 열거형(enum)이 바로 여기서 등장해.

열거형은 여러 개의 이름이 붙은 상수 집합을 선언할 수 있게 해주는 특별한 데이터 타입이야.
enum은 마치 칸마다 라벨이 붙은 상자 같은 거고, 각 라벨은 고유한 이름과 숫자가 연결되어 있어.

  • 코드가 읽기 쉽고 자기 설명적이 돼;
  • 0, 1, 2 같은 정체불명의 "매직 넘버" 대신 DayOfWeek.MondayTrafficLight.Red처럼 의미 있는 이름을 쓸 수 있어;
  • 잘못된 값을 넣으려고 하면 컴파일러가 에러를 내줄 거야;
  • 사실 각 요소는... 그냥 평범한 정수야! (이건 좀 있다가 다시 얘기할게.)

2. 열거형 선언 문법

우리 첫 번째 열거형을 만들어보자 — 날씨 타입을 위한 거야. 이렇게 쓸 수 있어:


// 날씨 상태 열거형
public enum WeatherCondition
{
    Sunny,       // 0
    Cloudy,      // 1
    Rainy,       // 2
    Stormy,      // 3
    Snowy        // 4
}
WeatherCondition 열거형 선언
  • enum 키워드로 새로운 타입을 정의해.
  • 중괄호 안에 선택지 이름을 써. 기본적으로 각 선택지는 0부터 시작하는 정수값이 자동으로 할당돼 (Sunny == 0, Cloudy == 1 등).
  • 값을 직접 지정할 수도 있어:
public enum WeatherCondition
{
    Sunny = 1,
    Cloudy = 2,
    Rainy = 4,
    Stormy = 8,
    Snowy = 16
}

이렇게 하면 외부 표준이나 프로토콜에 맞춰야 할 때 편해.

3. 열거형 사용하기

우리 작은 콘솔 앱을 만들었다고 해보자. 날씨에 따라 반응하는 프로그램이야.

// 앱 클래스
class Program
{
    static void Main()
    {
        // 날씨 상태 저장에 열거형 사용
        WeatherCondition todayWeather = WeatherCondition.Sunny;

        // 화면에 출력
        Console.WriteLine($"오늘 날씨: {todayWeather} ({(int)todayWeather})");

        // 날씨가 바뀌는 걸 흉내내보자
        todayWeather = WeatherCondition.Rainy;
        Console.WriteLine($"앗! 날씨가 바뀌었어: {todayWeather} ({(int)todayWeather})");
    }
}

무슨 일이 일어날까?


오늘 날씨: Sunny (0)
앗! 날씨가 바뀌었어: Rainy (2)
  • todayWeather문자열도 아니고 숫자도 아니고, 열거형의 요소야.
  • (int)로 캐스팅하면 해당 값의 "숫자 코드"를 볼 수 있어.

참고로, 열거형은 조건문이랑도 잘 어울려:

if (todayWeather == WeatherCondition.Rainy)
    Console.WriteLine("우산 챙겨!");

4. enum의 실전 활용 예시

열거형은 어디서 쓰일까?

  • 비즈니스 앱: 주문 상태 (New, Processing, Shipped, Cancelled).
  • 유저 관리 시스템: 권한 레벨 (User, Moderator, Admin).
  • 게임: 캐릭터 상태 (Idle, Moving, Jumping, Falling).
  • GUI: 버튼, 메시지, 아이콘 색상 등.

.NET에서라면 거의 표준 라이브러리의 절반에서 열거형을 볼 수 있어! 예를 들어 파일 작업할 때 파일 열기 모드(읽기, 쓰기, 생성 등)도 열거형으로 되어 있지.

5. 명시적 값과 값의 범위

가끔 코드에서 쓰는 int 값 집합을 enum으로 바꾸고 싶을 때가 있어. 이건 진짜 간단해:


public enum CompassDirection
{
    North = 10,
    East = 20,
    South = 30,
    West = 40
}
명시적 값이 있는 열거형

이제 CompassDirection.North = 10, East = 20 등등. 만약 어떤 요소에 값을 안 주면, 이전 값에서 +1이 자동으로 할당돼.

저장 타입

기본적으로 enumint(4바이트 정수)로 저장돼. 근데 메모리 아끼고 싶으면 기본 타입을 직접 지정할 수도 있어:

public enum TinyEnum : byte
{
    First,  // 0
    Second, // 1
    Third   // 2
}

이제 열거형 값 하나가 딱 1바이트!

가능한 타입 리스트: byte, sbyte, short, ushort, int, uint, long, ulong.

6. enum과 숫자/문자열 간 변환

enumint 변환:

enum을 int로, int를 enum으로 바꾸는 건 그냥 타입 캐스팅만 하면 돼:

WeatherCondition current = WeatherCondition.Cloudy;
int number = (int)current; // 1이 나옴

WeatherCondition fromNumber = (WeatherCondition)2; // Rainy가 나옴

enumstring 변환:

enum을 문자열로 바꾸려면 ToString()만 호출하면 돼.

// enum을 문자열로 변환
string name = WeatherCondition.Stormy.ToString(); // "Stormy"

// 문자열을 enum으로 변환 (Enum.Parse 사용)
WeatherCondition parsed = (WeatherCondition)Enum.Parse(typeof(WeatherCondition), "Stormy");

// Enum.TryParse도 쓸 수 있어
WeatherCondition parsedOk;
if (Enum.TryParse("Snowy", out parsedOk))
{
    Console.WriteLine(parsedOk); // Snowy
}

흔한 실수:
숫자를 enum으로 캐스팅할 때, 해당 값이 정의되어 있지 않아도 컴파일러는 에러를 안 내. 그냥 "가짜" 상태가 만들어질 뿐이야.
예시:

WeatherCondition weird = (WeatherCondition)999;
Console.WriteLine(weird); // 999 (이게 "Unknown"으로 바뀌지 않아!)

즉, 이런 변환을 할 땐 개발자가 신경 써야 해.

7. switchenum은 찰떡궁합

열거형(enum)은 switch문이랑 진짜 잘 어울려. 여러 if-else 없이도 각 값에 따라 "반응"하는 코드를 깔끔하게 쓸 수 있지.

예시: 날씨에 따른 반응

public enum WeatherCondition
{
    Sunny,
    Cloudy,
    Rainy,
    Stormy,
    Snowy
}

WeatherCondition today = WeatherCondition.Rainy;

switch (today)
{
    case WeatherCondition.Sunny:
        Console.WriteLine("맑음! 산책 가자.");
        break;
    case WeatherCondition.Cloudy:
        Console.WriteLine("흐림. 가디건 챙겨.");
        break;
    case WeatherCondition.Rainy:
        Console.WriteLine("비 온다. 우산 잊지 마!");
        break;
    case WeatherCondition.Stormy:
        Console.WriteLine("폭풍! 집에 있는 게 좋아.");
        break;
    case WeatherCondition.Snowy:
        Console.WriteLine("눈 온다 — 모자 써!");
        break;
    default:
        Console.WriteLine("알 수 없는 날씨...");
        break;
}
  • case는 열거형의 한 값을 의미해.
  • 아무 값에도 해당 안 되면 default가 실행돼 (예상치 못한 값이 들어올 때 유용해).

enum + switch 조합의 장점?

  • 코드가 읽기 쉬움: 가능한 모든 경우가 case로 한눈에 보여.
  • 확장도 쉬움: 새로운 날씨 타입 추가하면 case만 하나 더 쓰면 돼.
  • 안전함: (C# 8.0부터) 모든 경우를 다 처리했는지 컴파일러가 체크해줄 수도 있어.

예시: 게임용 enum과 로직

public enum GameState
{
    Start,
    Playing,
    Paused,
    GameOver
}

void PrintState(GameState state)
{
    switch (state)
    {
        case GameState.Start:
            Console.WriteLine("게임에 오신 걸 환영해!");
            break;
        case GameState.Playing:
            Console.WriteLine("게임 중. 행운을 빌어!");
            break;
        case GameState.Paused:
            Console.WriteLine("일시정지. 잠깐 쉬어가.");
            break;
        case GameState.GameOver:
            Console.WriteLine("게임 끝. 다시 도전해봐!");
            break;
        default:
            Console.WriteLine("알 수 없는 게임 상태.");
            break;
    }
}

팁:

  • 비슷한 동작이 여러 값에 필요하면 묶어서 처리해도 돼:
switch (today)
{
    case WeatherCondition.Rainy:
    case WeatherCondition.Stormy:
        Console.WriteLine("우산이랑 따뜻한 옷 챙겨!");
        break;
}
  • default도 꼭 써서 예상치 못한 값도 처리해 (예를 들어 누가 숫자를 enum으로 바로 캐스팅했을 때).
  • switch로 상태머신, 메뉴, 고정된 선택지 시스템 등도 쉽게 만들 수 있어.

8. 열거형과 .NET의 주요 메서드/서비스

.NET에는 열거형을 위한 유용한 메서드가 많아:

  • Enum.GetNames(typeof(WeatherCondition)) — 모든 이름 가져오기.
  • Enum.GetValues(typeof(WeatherCondition)) — 모든 값 가져오기.
  • Enum.IsDefined(typeof(WeatherCondition), "Rainy") — 해당 멤버가 있는지 확인.
  • 문서: System.Enum

모든 날씨 타입 출력 예시:

foreach (var name in Enum.GetNames(typeof(WeatherCondition)))
{
    Console.WriteLine(name);
}

9. 흔한 실수와 "지뢰"

  • 열거형 대신 "매직 넘버"를 써서 코드가 읽기 힘들어짐.
  • 열거형에 정의되지 않은 값 처리를 안 함 (숫자 캐스팅 예시 참고).
  • 의미 없는 이름(Value1, Value2...)을 써서 나중에 아무도 뭔지 모르게 됨.
  • 한 열거형에 여러 종류의 의미를 섞어서 단일 책임 원칙을 깨뜨림.

최고의 방법: 선택지가 정해져 있으면 항상 열거형을 쓰고, 각 요소에 의미 있고 자기 설명적인 이름을 붙여!

코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION