열거 형을 문자열로 변환


163

.NET 3.5에서 Enum을 String으로 변환하는 가장 좋은 방법은 무엇입니까?

  • 열거 형 GetName
  • 열거 형식
  • ToString

왜이 중 하나를 다른 것보다 선호해야합니까? 하나 더 잘 수행합니까?


10
검색하여 사본을 찾을 수 없습니다. 링크를 제공 할 수 있으면이 질문을 삭제하겠습니다.
Eric Weilnau

1
때때로, switch 문을 사용하는 대신 가장 좋은 방법은 (당신이 큰 열거있을 때) 당신이 DICT을 <사용>되지 않습니다
가이 L

1
더 나은 성능을 원한다면이 기사 codeproject.com/KB/dotnet/enum.aspx에 설명 된 클래스를 사용할 수 있습니다 . 사용이 열거 <YourEnum>로 .toString (yourValue) 또는 열거 모양을 <YourEnum>로 .toString ((int)를 yourValue)
ideafixxxer

5
닷 퓨징을 끊지 않도록 코딩하는 것은 개를 흔드는 꼬리의 전형이다. SW 제작자들은 "dotfuscator가 할 수있는 좋은 앱을 만들어 보자"고 생각하지 않습니다. SW 개발을 촉진하기 위해 Dofuscator가 있습니다. 그렇게 할 수 없다면 ... 할 수 있습니다!
micahhoover

답변:


127

C # 6부터 열거 형의 이름을 얻는 가장 좋은 방법은 새로운 nameof연산자입니다.

nameof(MyEnum.EnumValue);

// Ouputs
> "EnumValue"

컴파일 타임에 열거 형이 컴파일 된 결과의 문자열로 바뀌어 작동하며, 이것이 가장 빠른 방법임을 의미합니다.

열거 형 이름의 난독 화가 가치 있거나 중요하다고 생각되면 열거 형 이름을 사용하면 코드 난독 화를 방해 할 수 있습니다. 이는 아마도 다른 질문 일 것입니다.


11
더주의를 기울여야합니다. 그럼에도 불구하고 명백한 한계, 즉 컴파일 타임 입력 요구 사항. 제 생각에 이것은 가능할 때마다 선호되어야 합니다 . '이름 바꾸기'및 '모든 참조 찾기'도이를 고려하여 마술 문자열과 중복 상수를 피할 수 있습니다.
Timo

1
그래서 열거 형 값이 런타임에 정의되면 작동하지 않는 것 같습니다. 예 : MyEnum variableEnum; variableEnum = setEnumValueMethod (); nameof (variableEnum);
Maxter

1
어떤 @Maxter과 같은 nameof(variableEnum)것입니다 "variableEnum". 값이 아닌 필드 / 속성 / 매개 변수 / 변수 의 이름 을 (빌드 타임에) 반영 합니다 .
Keith

이인칭 대명사. 이렇게하면 안타깝게도 작동하지 않습니다. var someEnumvalue = SomeEnum.FooBar; nameof (someEnumvalue);
Squibly November

1
@Squibly 네, 반환 "someEnumValue"당신이 필요로 할 때, nameof(SomeEnum.FooBar)얻을 "FooBar".
Keith는

93

우리 프로젝트를 위해 일하십시오 ...

public static String convertToString(this Enum eff)
{
    return Enum.GetName(eff.GetType(), eff);
}

public static EnumType converToEnum<EnumType>(this String enumValue)  
{
    return (EnumType) Enum.Parse(typeof(EnumType), enumValue);
}

7
Enum.GetName은 값을 객체 인수로 사용합니다. 즉, 값이 박스로 표시되어 할당 및 가비지 수집시 CPU 리소스가 낭비됩니다. 이 작업을 많이 수행하면 Enum.GetName은 사전의 값을 캐싱하고 해당 이름을 찾는 것보다 처리량이 훨씬 적습니다.

@ Ran 그래서 해결책은 무엇입니까, 대신 사용해야합니까?
shaijut

이것이 답이되어야합니다
Squibly

내 프로젝트가 느려집니다. toString ()이 더 빠릅니다.
d2k2

29

내 테스트에서 Enum.GetName더 빠르고 괜찮은 마진이있었습니다. 내부적으로 ToString호출합니다 Enum.GetName. .NET 4.0 용 소스 에서 필수 사항 :

public override String ToString()
{
     return Enum.InternalFormat((RuntimeType)GetType(), GetValue());
}

private static String InternalFormat(RuntimeType eT, Object value)
{
    if (!eT.IsDefined(typeof(System.FlagsAttribute), false))
    {
        String retval = GetName(eT, value); //<== the one
        if (retval == null)
            return value.ToString();
        else
            return retval;
    }
    else
    {
        return InternalFlagsFormat(eT, value);
    }
}

나는 그것이 확실한 이유라고 말할 수는 없지만 테스트는 하나가 다른 것보다 빠릅니다. 두 통화 모두 권투와 관련이 있으며 (실제로 리플렉션 통화이므로 필드 이름을 검색하는 중임) 원하는대로 느릴 수 있습니다.

테스트 설정 : 8 개의 값을 가진 열거 형, 아니요. 반복 횟수 = 1000000

결과 : Enum.GetName => 700 ms, ToString => 2000 ms

속도가 눈에 띄지 않으면 ToString훨씬 깨끗한 통화를 제공하므로 신경 쓰지 않고 사용하지 않습니다 . 대조

Enum.GetName(typeof(Bla), value)

value.ToString()

25

Enum.GetName (...)

이것은 가장 우아한 방법입니다.

var enumValueString = Enum.GetName(typeof (MyEnum), MyEnum.MyValue);

전화 .ToString()시간이 짧기 때문에 전화 문제는 보이지 않습니다 .

var enumValueString = MyEnum.MyValue.ToString();

새로운 C # 6 구문으로 다음을 사용할 수 있습니다.

nameof(MyEnum.MyValue)

20

내부적으로는 모두라는 메소드를 호출 InternalGetValueAsString합니다. 의 차이 ToStringGetName그 것이다 GetName먼저 몇 가지를 확인해야합니다 :

  1. 입력하신 유형이 null이 아닙니다.
  2. 입력 한 유형은 실제로 열거 형입니다.
  3. 전달한 값이 null이 아닙니다.
  4. 전달한 값은 열거 형이 실제로 기본 유형으로 사용할 수있는 유형이거나 열거 형 자체의 유형입니다. GetType이를 확인하기 위해 값을 사용 합니다.

.ToString위의 문제는 클래스 자체가 아니라 전달 된 버전이 아니라 호출되므로 .ToString메소드에 동일한 확인 문제 가 없기 때문에 위의 문제에 대해 걱정할 필요 가 없습니다. 정적 방법으로, .ToString값을 문자열로 얻는 가장 빠른 방법 이라고 결론 내릴 것 입니다.


2
어디서 확인 했습니까? 어셈블리 버전은 무엇입니까? 나는 매우 다른 결과를 얻습니다.
nawfal

17

내가 찾을 수있는 가장 좋은 것은 MSDN 에서이 관련이없는 질문입니다 . 이러한 방법은 모두 같은 결함을 공유합니다. 즉 enum.toString(), Dotfuscation을 사용할 때 제대로 작동하지 않습니다 . 다른 문제는 간접 권투 (GetName 및 Format)와 관련이있는 것으로 보입니다. 불행히도, 위의 것을 사용하는 성능상의 이유를 찾을 수 없습니다.

으로부터 의역 XML 조각 ,

boxed 열거 형을 string.Format () 또는 다른 함수에 전달하면 enum.ToString()호출 될 수 있습니다 . Dotfuscating 때 문제가 발생합니다. 당신은 사용하지 말아야합니다 enum.ToString(), enum.GetNames(), enum.GetName(), enum.Format()또는 enum.Parse()문자열로 열거를 변환 할 수 있습니다. 대신 switch 문을 사용하고 필요한 경우 이름을 국제화하십시오.


16

Enum.GetName()

Format()실제로 GetName()일부 서식 기능 (또는 InternalGetValueAsString()정확) 으로 래퍼 입니다. ToString()와 거의 동일합니다 Format(). 나는 GetName()소스를 읽는 사람에게 무엇을 하는지를 완전히 알기 때문에 최선의 선택 이라고 생각 합니다.


8

"설명"확장 방법을 만들고 열거 형에 첨부하여 공백과 케이스가 포함 된 사용자에게 친숙한 이름을 지정할 수 있습니다. 나는 열거 형 값 자체를 표시 가능한 텍스트로 사용하는 것을 좋아하지 않았습니다. 개발자가 더 읽기 쉬운 코드를 만드는 데 사용하기 때문입니다. UI 표시 용이 아닙니다. 열거 형을 통하지 않고 UI를 변경하고 싶습니다.


6

나는 "선호하는"방법이 무엇인지 모르지만 (100 명에게 물어보고 100 개의 다른 의견을 얻음) 가장 단순하고 효과적인 방법을 수행합니다. GetName작동하지만 더 많은 키 입력이 필요합니다. ToString()일을 아주 잘하는 것 같습니다.


1

VB 애호가의 경우 :

EnumStringValue = System.Enum.GetName(GetType(MyEnum), MyEnumValue)

0

이것도 효과가 있습니다.

    List<string> names = Enum.GetNames(typeof(MyEnum)).ToList();

0

ToString()가독성 관점에서 가장 확실한 결과를 제공 하지만 사용 Enum.GetName()하려면 패턴을 항상 보지 않는 한 사용하려는 작업을 신속하게 이해하기 위해 약간 더 정신 분석이 필요합니다.

@nawfal의 답변에 이미 제공된 것처럼 순수한 성능 관점에서 Enum.GetName()더 좋습니다.

성능이 실제로 목표라면 사전 또는 다른 매핑을 사용하여 미리 조회를 제공하는 것이 좋습니다.

C ++ / CLI에서는 다음과 같습니다.

Dictionary<String^, MyEnum> mapping;
for each (MyEnum field in Enum::GetValues(MyEnum::typeid))
{
    mapping.Add(Enum::GetName(MyEnum::typeid), field);
}

100 개 항목과 1000000 회 반복의 열거 형을 사용한 비교 :

Enum.GetName : ~ 800ms
.ToString () : ~ 1600ms
사전 매핑 : ~ 250ms


-3

단순 : 열거 형 이름을 목록으로 :

List<String> NameList = Enum.GetNames(typeof(YourEnumName)).Cast<string>().ToList()

@Brian 안녕하세요, GetNames ()의 출력을 캐스트 할 필요는 없다고 생각합니다
Nic
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.