CSharp Enum 과 상수(Constant)

양승준·2025년 4월 3일

CSharp

목록 보기
13/20
post-thumbnail

시작하며

안녕하신가? 오늘도 작성하러 왔다네, 왔다네.
요즘 생각하는건데, 이제는 여기가 일기장 같은 느낌이다. 오늘은 무엇을 했다는 적는...ㅋㅋ

그래서 오늘 할 포스팅은 Enumconst 이다.
Enum은 코딩의 가독성을 높여주는데 나는 자주 사용한다.
const상수인데 한 번 지정하면 변경할 수 없다.
이번에는 이 둘의 활용 방안들을 정리해 미래의 나에게 도움이 되길 😆 (오글..ㅋㅋ)


✅ 상수란?

사전적 의미

수식에서 변하지 않는 값

프로그래밍에서의 의미

값이 변경되지 않는 데이터를 표현하기 위해 사용하는 것

내 방식대로 풀자면,

  • 변수는 "변할 수 있는 수"
  • 상수는 "변하지 않는 수"

영어로는 constant — "변함없는"
한자로는 상수(常數) → "항상 일정한 수"


상수 사용

상수를 나타내는 C# 키워드는 대표적으로 두 가지! const, readonly

const

const 키워드, 이 키워드는 사용이 참 편리하다 어디서든 접근이 가능하다. 인스턴스라고 하는 실체화를 해주지 않아도 말이다. (?) 이것을 몰랐던 당신! 그럴 수 있다. 나도 정리하면서 알았다. ㅋㅋㅋ...;;

해당 키워드를 사용해서 상수를 선언 시 반드시 초기화를 진행해줘야된다.

const double Pi = 3.14159;
const int MaxValue = 100;
const int Error; // 이런 식으로 선언하면 컴파일 에러 발생한다. > const 필드에 값을 입력해야합니다.

const의 특징

  • 컴파일 시간에 값이 결정된다.
  • 선언 시 반드시 초기화해야 하며, 변경이 불가하다.
  • 기본적으로 static 처럼 동작한다.(instance 없이 접근 가능)
    instance: 어떠한 설계도가 있으면 그 설계도데로 실체화를 해주는 행동

이렇게 위와 같은 특징들이 존재한다. 코딩을 한다면 이러한 특징들을 유의하면 작성해야된다.
비유 하자면 메인보드를 동작 시키는 칩에 공장에서 제조할 때, 메인보드 프로그램을 내장 시켜서 제조 시키는 거와 같은 느낌이다.


readonly

readonly 는 한번 초기화가 가능한 상수를 선언할 수 있게 해주는 키워드이다.

internal class Program
{
    static void Main(string[] args)
    {
    	Config config = new Config(10); // 내부 WriteLine 5 출력
		Console.WriteLine(config.MaxSize); // 외부에서 생성자로 생성후 호출, 출력시 10
    }
}

class Config
{
    public readonly int MaxSize = 5; // 1. 선언 시 초기화 진행

    public Config(int size)
    {
    	Console.WriteLine(MaxSize);
        MaxSize = size; // 2. 생성자안에 사용하여 초기화 진행
    }
}

특징

  • 런타임 시 초기화 가능한 상수
  • 최초는 선언 시, 초기화가 진행된다.
  • 생성자에서만 값을 설정할 수 있으며, 이후 변경 불가
  • 주로 클래스 필드로 사용됨.
    > 주의 해야될 것은, readonly는 객체마다 다른 값을 가질수 있다는 점에서 const와 다르다.

위와 같은 특징들을 지니는데, 비유하자면 옛날에 CD 중에서 한번 데이터를 넣어주면, 변경 못하던 CD 가 있다. 그 CD의 느낌이다. 친구한테 내가 가지고 있는 게임을 CD에 복사해줬던 느낌... ㅋㅋㅋ(벌써 15년도 더 된 이야기라니 ㅠ.ㅠ)


✅ Enum == 열거형, Trun

이번에는 코드에서는 Enum, 한국어로는 열거형~ 이라는 녀석을 정리해 보겠다.

열거란?

여러 항목을 나열해 하나하나 들어 보이는 것
열(列) + 거(擧) → 줄 세워 뽑아내다

Enum이란?

enum은 열거형이라고도 하며, 관련 있는 상수들을 한데 묶어서 "나열"하는 것이다. 예를 들어 장비라는 열거형이 있다면 무기, 방어구, 장신구 들이 있을 것이다. 이 것을 enum으로 표현한다면?

🧪 기본 선언

/// <summary>
/// 장비의 종류를 구분하는 열거형(enum)
/// </summary>
public enum EquipmentType
{
    Weapon,     // 무기 0
    Armor,      // 방어구 1
    Accessory   // 장신구 2
}

위과 같은 방식으로 표현이 가능하다. 그리고 enum은 하나의 자료형 타입으로 지정되며, 값 타입의 형태를 가집니다.

  • 관련 있는 상수들을 한 데 묶음
  • 하나의 자료형으로 사용 가능(int로 매핑됨)
  • 기본값은 0부터 시작하여 자동으로 1씩 증가

Enum 사용

그럼. 이번에는 Enum을 사용입니다. enum을 작성하고, 해당 안의 값들이 어떤식으로 지정되고 사용되는지입니다.

먼저 enum 형은 int형 상수입니다. 한 마디로 숫자 값을 넣을 수 있다는 거죠.

🧪 선언

// 값을 지정 가능
public enum EquipmentType
{
    Weapon = 10,     // 무기 10
    Armor,      // 방어구 11
    Accessory = 100   // 장신구 100
}

// 이런식으로 작성할 수 있고 에러도 나지 않는다. 
// 대신 정수 10을 해당 형으로 변형 한다면, 무조건 앞에 오는 Weapon으로 판별도니다.
public enum TestAEnum
{
    Weapon = -10,     // 무기 -10
    Armor,      // 방어구 -9
    Accessory = 10   // 장신구 10
}

// 이러한 식으로 작성하면, 이러한 식으로 중간에 값을 작성하면 그 뒤는 해당 값을 기준으로 1씩 늘어나 지정된다.
public enum TestBEnum
{
	A = 900, // 900
	B,       // 901
    C = 10,  // 10
    D,       // 11
}

// 이 처럼, 실수형이 아닌 정수형으로 최소 최대 값의 범위를 늘려줄 수 있다.
// 실수형(float, double)이나 decimal, 참조형 타입은 절대 안 됩니다.
public enum TestCEnum : long
{
    A = 900, // 900
    B,       // 901
    C = 10,  // 10
    D,       // 11
}

위와 같이 많은 방법으로 enum 을 만들고 수정하여, 값을 지정 가능하다.


활용

🧪 활용 1

EquipmentType type = EquipmentType.Weapon;
Console.WriteLine((int)type); // 출력: 0

위와 같은 식으로 enum 값을 지정했다면. 그 값을 기반으로 알맞은 int 값으로 표현이 가능하다.

🧪 활용 2

internal class Program
{
    // 기본 선언
    public enum EquipmentType
    {
        Weapon,    // 무기    0
        Armor,     // 방어구  1
        Accessory  // 장신구  2
    }

    static void Main(string[] args)
    {
        Console.WriteLine("얻고 싶은 장비 번호를 선택하시요.");
        Console.WriteLine("0. 무기");
        Console.WriteLine("1. 방어구");
        Console.WriteLine("2. 장신구");
        
        Console.Write("[입력]: ");
        int inputValue;
        int.TryParse(Console.ReadLine(), out inputValue); 

        Console.WriteLine($"획득한 장비: {GetEquipment(inputValue)}");
    }

    public static EquipmentType GetEquipment(int value)
    {
        return (EquipmentType)value;
    }
}

입력을 안하고 Enter 시

얻고 싶은 장비 번호를 선택하시요.
1. 무기
2. 방어구
3. 장신구
[입력]:
획득한 장비: Weapon

  • 기본 값 0 이 들어와서 Weapon 출력

알맞은 값 입력 시

얻고 싶은 장비 번호를 선택하시요.
0. 무기
1. 방어구
2. 장신구
[입력]: 1
획득한 장비: Armor

  • 입력 값 1 이 들어와서 Armor 출력

잘못된 값 입력 시

얻고 싶은 장비 번호를 선택하시요.
0. 무기
1. 방어구
2. 장신구
[입력]: -10
획득한 장비: -10

  • 잘못된 값 입력 시는 해당 값이 출력되는 것을 볼 수 있다.

Enum 특징

  • enum 의 지정 값은 음수도 가능하다.
  • enum 이 지정된 값에 알맞은 정수 값으로 변환을 시도한다면 지정된 enum 으로 변환된다.
  • 잘못된 정수 값도 저장이 가능하다.
  • 잘못된 정수 값 저장하고, 그 변수를 enum으로 변환을 시도한다여 출력한다면, 그 잘못된 값인 정수가 출력된다.
  • enum은 기본적으로 int 이지만, 다른 정수형을 기반으로 선언이 가능하다.( byte, short, int, long 등 )


Enum Flags

열거형을 비트 필드 즉, 플래그(Flags) 집합으로 처리할 수 있음을 나타내는 것이다. [Flags] enum 을 사용할 때, 각 항목은 2진수(비트) 의 각 자리에 대응된다. 하나의 enum 변수에 여러 개의 값(상태) 를 동시에 넣을 수 있다.

🧪 [Flags] 선언

[Flag]
enum FlagsTest 
{
	None = 0,
	Read = 1,       // 0001
    Write = 2,      // 0010
    Execute = 4     // 0100
}

🧪 Enum Flags 사용법

장비 착용 관련하여서 간단한 코드를 작성했다.

using System;

[Flags]
public enum EquipmentType
{
    None       = 0,
    Weapon     = 1 << 0,   // 1
    Armor      = 1 << 1,   // 2
    Accessory  = 1 << 2,   // 4
    Shield     = 1 << 3,   // 8
    Ring       = 1 << 4    // 16
}

class Program
{
    static void Main(string[] args)
    {
        EquipmentType equippedItems = EquipmentType.Weapon | EquipmentType.Armor;

        Console.WriteLine($"현재 장비: {equippedItems}");

        // 장비 확인
        Console.WriteLine($"무기 착용 여부: {equippedItems.HasFlag(EquipmentType.Weapon)}");
        Console.WriteLine($"반지 착용 여부: {equippedItems.HasFlag(EquipmentType.Ring)}");

        // 장비 추가
        equippedItems |= EquipmentType.Ring;
        Console.WriteLine($"[반지 장착 후] 현재 장비: {equippedItems}");

        // 장비 제거
        equippedItems &= ~EquipmentType.Weapon;
        Console.WriteLine($"[무기 제거 후] 현재 장비: {equippedItems}");
    }
}

현재 장비: Weapon, Armor
무기 착용 여부: True
반지 착용 여부: False
[반지 장착 후] 현재 장비: Weapon, Armor, Ring
[무기 제거 후] 현재 장비: Armor, Ring

이렇게 비트연산으로 장비의 착용 유무나 버프 디버프의 유무를 확인하는데에 사용할 수 있다.

그리고 이것의 장단점은

[Flags] Enum 장점

장점설명
복합 상태 표현하나의 변수로 여러 상태(옵션)을 동시에 저장 가능
비트 연산 효율|, &, ^, ~ 같은 비트 연산으로 빠르고 간단하게 조작 가능
메모리 절약여러 Boolean 값을 따로 저장하지 않고 하나의 정수로 관리
조건 검사 용이.HasFlag() 또는 & 연산자로 플래그 포함 여부 쉽게 확인 가능

[Flags] Enum 단점

단점설명
실수하기 쉬움잘못된 비트 값 조합(중복된 비트, 0값 포함 등)으로 의도치 않은 결과 발생 가능
디버깅 어려움여러 플래그가 섞인 값을 디버깅 시 해석이 어려울 수 있음
Enum 간 조합 주의다른 Enum끼리 조합하면 의미 없는 결과 발생 가능 (컴파일은 되나 오류!!!)

마치며

이렇게 정리하면서, 내가 알고 있는 것이 명확해지는 기분이다. 기존에 잘하고 있다고 생각했는데 더욱 많은 방면으로 사용할 수 있었구나와 내가 틀에 갇혀서 활용을 제대로 못하였구나라는 생각이 든다.

  • 상수는 const, readonly를 사용하여 선언 할 수 있다.
  • conststatic 처럼 전역에 사용가능하며, 인스턴스화를 진행하지 않아도 사용가능하다.
  • readonly는 선언 시 값을 넣어 초기화를 진행 할 수 있다.
  • readonly는 선언 후, 생성자를 사용하여 값을 할당할 수 있다.
  • enum은 지정한 문자에 수가 대응 되는 형태이다.
  • enum 음수도 사용가능하다.
  • [Flags] enum 은 비트 연산이 가능하여, 하나의 변수에 여러 상태를 넣어줄 수 있어서 메모리적으로 좋다.
profile
지모창말, 미모창.

0개의 댓글