C# - enum 값을 int로 암시적(implicit) 형변환하는 방법?
때로는 enum 값이 int로 암시적 형변환이 있었으면 좋을 때가 있습니다.
C# 7.3에서 enum을 boxing 없이 int로 변환하기 - 세 번째 이야기
; https://www.sysnet.pe.kr/2/0/11565
위의 박싱 문제 말고도 어떤 경우에는 다양한 enum 값을 받아야 할 수도 있는데요, 그럴 때 보통 int로 처리하게 됩니다.
using System;
class Program
{
static void Main(string[] args)
{
PrintEnumValue((int)Project.Debug);
PrintEnumValue((int)Solution.Project);
}
private static void PrintEnumValue(int value)
{
Console.WriteLine(value);
}
}
enum Project
{
Debug = 1,
Release = 2,
}
enum Solution
{
Project = 3,
Item = 4,
}
보는 바와 같이, 매번 전달할 때 (int) 형변환하는 것이 꽤나 귀찮은 문제입니다. (좀 더 엄밀히 따지면, 이건 귀찮음의 문제가 아니라 개발자라는 직업의 성격상 뭔가,,, 마음속 깊이 받아들여지지 않는 무언가가 있습니다. ^^;)
어쩌면 이에 대한 이상적인 해결책은, 그러니까 기존 문법에 기반을 둬 추가한다면 enum 타입에서도 연산자 재정의를 지원하는 것입니다.
enum Project
{
Debug = 1,
Release = 2,
// 지원하지 않는 문법: 컴파일 오류
public static implicit operator int(Project value)
{
return (int)value;
}
}
enum Solution
{
Project = 3,
Item = 4,
// 지원하지 않는 문법: 컴파일 오류
public static implicit operator int(Solution value)
{
return (int)value;
}
}
보다시피, 지원하지 않는다는 것이 문제라서. ^^;
이에 대해 검색해 보면, 그나마 최선의 방법을 다음의 Q&A에서 보게 됩니다.
Can we define implicit conversions of enums in c#?
; https://stackoverflow.com/questions/261663/can-we-define-implicit-conversions-of-enums-in-c
덧글에 보면 중계 타입으로 PrimitiveEnum을 정의하고 있는데요,
McKabue.Extentions.Utility/src/McKabue.Extentions.Utility/Enums/PrimitiveEnum.cs
; https://github.com/McKabue/McKabue.Extentions.Utility/blob/master/src/McKabue.Extentions.Utility/Enums/PrimitiveEnum.cs
using System;
using System.Collections.Generic;
using System.Text;
public class PrimitiveEnum
{
private Enum _enum;
public PrimitiveEnum(Enum _enum)
{
this._enum = _enum;
}
public Enum Enum => _enum;
public static implicit operator PrimitiveEnum(Enum _enum)
{
return new PrimitiveEnum(_enum);
}
public static implicit operator Enum(PrimitiveEnum primitiveEnum)
{
return primitiveEnum.Enum;
}
public static implicit operator byte(PrimitiveEnum primitiveEnum)
{
return Convert.ToByte(primitiveEnum.Enum);
}
public static implicit operator sbyte(PrimitiveEnum primitiveEnum)
{
return Convert.ToSByte(primitiveEnum.Enum);
}
public static implicit operator short(PrimitiveEnum primitiveEnum)
{
return Convert.ToInt16(primitiveEnum.Enum);
}
public static implicit operator ushort(PrimitiveEnum primitiveEnum)
{
return Convert.ToUInt16(primitiveEnum.Enum);
}
public static implicit operator int(PrimitiveEnum primitiveEnum)
{
return Convert.ToInt32(primitiveEnum.Enum);
}
public static implicit operator uint(PrimitiveEnum primitiveEnum)
{
return Convert.ToUInt32(primitiveEnum.Enum);
}
public static implicit operator long(PrimitiveEnum primitiveEnum)
{
return Convert.ToInt64(primitiveEnum.Enum);
}
public static implicit operator ulong(PrimitiveEnum primitiveEnum)
{
return Convert.ToUInt64(primitiveEnum.Enum);
}
}
이것을 이용하면 enum 타입을 쓰면서도 자연스럽게 int로 형변환하는 것이 가능합니다.
static void Main(string[] args)
{
PrintEnumValue(Project.Debug);
PrintEnumValue(Solution.Project);
}
/* 출력 결과
1
Debug
3
Project
*/
private static void PrintEnumValue(PrimitiveEnum value)
{
int intValue = value; // 암시적 형변환 (박싱 발생)
Console.WriteLine(intValue); // 출력: 정숫값
Console.WriteLine(value.Enum); // 출력: enum 문자열
}
/*
private static void PrintEnumValue(Enum value)
{
int intValue = Convert.ToInt32(value); // (박싱 발생)
Console.WriteLine(intValue); // 출력: 정숫값
Console.WriteLine(value); // 출력: enum 문자열
}
*/
현재로서는, 이 정도 수준이 최선일 듯합니다.
(
첨부 파일은 이 글의 예제 코드를 포함합니다.)
[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]