2017-12-19 7 views
0

나는 열거 값에 대한 StringValue 속성을 가진, 그래서 각각의 값에 대한 설명을 첨부 할 수 있습니다 :enum 값 특성의 IEnumerable <string>을 얻는 방법?

public class StringValueAttribute : Attribute 
{ 
    public string Value { get; private set; } 

    public StringValueAttribute(string value) 
    { 
     Value = value; 
    } 
} 

을 그리고 내가 그것을 사용하는 방법입니다 :

enum Group 
{ 
    [StringValue("Computer Science")] 
    ComputerScience, 

    [StringValue("Software Engineering")] 
    SoftwareEngineering, 

    // ... additional values follow. 
} 

나는를 검색하는 방법을 StringValue이 열거 값 주어진 :

public static string GetStringValue(Enum value) 
{ 
    Type type = value.GetType(); 
    FieldInfo fieldInfo = type.GetField(type.ToString()); 
    StringValueAttribute[] attributes = fieldInfo.GetCustomAttributes(typeof(StringValueAttribute), false) as StringValueAttribute[]; 

    string stringValue = null; 
    if (attributes.Length > 0) 
    { 
     stringValue = attributes[0].Value; 
    } 

    return stringValue; 
} 

내가 열거 얻는 다른 방법을 갖고 싶어 (열거 자체를하지 값)을 nd는 GetStringValue 메소드를 사용하여 IEnumerable을 검색합니다. 나는 그것을 성취하는 방법을 잘 모르겠습니다. 이 방법은 어떻게 생겼습니까?


편집 :이 질문은 How to get C# Enum description from value?의 중복이 아니다. 열거 형 속성 값을 얻는 방법을 알고 있습니다. 실제로 그 일을 정확하게 수행하는 방법이 있습니다. 내 질문에 열거 형의 모든 특성을 열거하는 방법입니다.

+0

당신은 당신이'GetStringValues ​​()'일반적인 방법을 원하는거야? – dbc

+1

사용자 정의 속성 대신 기존의'DescriptionAttribute'를 사용할 수 있습니다. enum.GetValues ​​(typeof (EnumType)) 캐스트 () .Select (/ * 메서드 호출 * /)' –

+0

@dbc - 그런 식으로. 그러나 [여기] (https://stackoverflow.com/a/27101267/1925272) 그런 방법을 일반적인 것으로 만들지 않는 것이 좋습니다. – Sipo

답변

2

이 작업을 수행하는 가장 간단한 방법은, 일반적인 함께 모든 값 :

public static class EnumExtensions 
{ 
    public static IEnumerable<string> GetStringValues<TEnum>() where TEnum : struct, IConvertible, IComparable, IFormattable 
    { 
     return Enum.GetValues(typeof(TEnum)) 
      .Cast<Enum>() 
      .Select(e => e.GetStringValue()) 
      .ToList(); 
    } 

    public static IEnumerable<string> GetStringValuesOfType(Enum value) 
    { 
     return Enum.GetValues(value.GetType()) 
      .Cast<Enum>() 
      .Select(e => e.GetStringValue()) 
      .ToList(); 
    } 

    public static string GetStringValue(this Enum value) 
    { 
     Type type = value.GetType(); 
     FieldInfo fieldInfo = type.GetField(value.ToString()); 
     StringValueAttribute[] attributes = fieldInfo.GetCustomAttributes(typeof(StringValueAttribute), false) as StringValueAttribute[]; 

     string stringValue = null; 
     if (attributes.Length > 0) 
     { 
      stringValue = attributes[0].Value; 
     } 

     return stringValue; 
    } 
} 

주 :

  • C#에 where TEnum : Enum 제약 조건이 없습니다. TEnumstruct, IConvertible, IComparable, IFormattable으로 제한하는 것은 대부분은입니다. 상기되는 그게

  • SLaks에 의해 Enum type constraints in C#this answer에 도시 된 enum 제약을 적용하기 교활한 트릭있다. (나는 그것이 정말 교활한 이후하지만이 답변에서 사용하지 않았다.)

  • @ EdPlunkett의 코멘트에서 언급 한 바와 같이 당신이 특정 수신 enum 값에 대응하는 필드를 얻고 있기 때문에 당신이 type.GetField()value.ToString()를 전달해야 .

샘플 fiddle

+0

완벽하게 작동합니다. 감사. – Sipo

1

이 작동합니다 : 당신은 항상 다음의 StringValue 값을 반환, 특정 Enum의 인스턴스를 전달 유형을 얻을 수 있지만

static void Main(string[] args) 
{ 
    foreach (var item in GetStringNames<Group>()) 
    { 
     Console.WriteLine(item); 
    } 
} 
public static string GetStringValue(Enum value) 
{ 
    Type type = value.GetType(); 
    FieldInfo fieldInfo = type.GetField(value.ToString()); 
    StringValueAttribute[] attributes = fieldInfo.GetCustomAttributes(typeof(StringValueAttribute), false) as StringValueAttribute[]; 

    string stringValue = null; 
    if (attributes.Length > 0) 
    { 
     stringValue = attributes[0].Value; 
    } 

    return stringValue; 
} 

public static IEnumerable<string> GetStringNames<T>() 
{ 
    var type = typeof(T); 

    if (type.IsEnum == false) 
    { 
     throw new ArgumentException("T must be an Enum type"); 
    } 

    var values = type.GetEnumValues(); 

    foreach (var item in values) 
    { 
     yield return GetStringValue((Enum)item); 
    } 
} 
+0

감사합니다. @ dbc의 대답은 내 프로그램에 더 적합하기 때문에 선택했습니다. 그러나 대답은 잘 된 것처럼 보입니다. – Sipo