문자열 값이 열거 형 목록에 있는지 확인하는 방법은 무엇입니까?


92

내 쿼리 문자열에는 age 변수가 ?age=New_Born있습니다.

이 문자열 값 New_Born이 내 Enum 목록에 있는지 확인할 수있는 방법이 있습니까?

[Flags]
public enum Age
{
    New_Born = 1,
    Toddler = 2,
    Preschool = 4,
    Kindergarten = 8
}

지금은 if 문을 사용할 수 있지만 Enum 목록이 커지면 사용할 수 있습니다. 더 나은 방법을 찾고 싶습니다. 나는 Linq를 사용하려고 생각하고 있지만 어떻게 해야할지 모르겠습니다.


3
Enum.IsDefined괜찮아?
leppie

답변:


155

당신이 사용할 수있는:

 Enum.IsDefined(typeof(Age), youragevariable)

다음 IsDefined 확인하기 위해 열거 인스턴스가 필요합니다
비아체슬라프 Smityukh에게

9
Enum.IsDefined()대소 문자를 구분 한다는 것을 기억하십시오 ! 그래서 그것은 "보편적 인 해결책"이 아닙니다.
Cheshire Cat

7
IsDefined는 리플렉션을 사용하기 때문에 일반적으로 IsDefined를 사용하지 않는 것이 좋습니다. 성능 및 CPU 측면에서 IsDefined를 호출하면 비용이 매우 많이 듭니다. 대신 TryParse를 사용하십시오. (pluralsight.com에서 배운)
웨이 후이시 구오에게

41

Enum.TryParse 메서드를 사용할 수 있습니다.

Age age;
if (Enum.TryParse<Age>("New_Born", out age))
{
    // You now have the value in age 
}

5
이것은 .NET 4 등 만 사용할 수 있습니다
게리 리히터

2
이것의 문제는 당신이 어떤 정수 ( "New_Born"문자열 대신에)를 제공하면 참을 반환한다는 것입니다.
로맹 빈센트

10

성공하면 true를 반환 하는 TryParse 메서드를 사용할 수 있습니다 .

Age age;

if(Enum.TryParse<Age>("myString", out age))
{
   //Here you can use age
}

2

IsDefined는 대소 문자를 구분하므로 TryParse를 사용하는 편리한 확장 방법이 있습니다.

public static bool IsParsable<T>(this string value) where T : struct
{
    return Enum.TryParse<T>(value, true, out _);
}

1

Enum.TryParse를 사용하여 목표를 달성해야합니다.

다음은 예입니다.

[Flags]
private enum TestEnum
{
    Value1 = 1,
    Value2 = 2
}

static void Main(string[] args)
{
    var enumName = "Value1";
    TestEnum enumValue;

    if (!TestEnum.TryParse(enumName, out enumValue))
    {
        throw new Exception("Wrong enum value");
    }

    // enumValue contains parsed value
}

1

이것이 오래된 스레드라는 것을 알고 있지만 Enumerates의 속성을 사용하는 약간 다른 접근 방식과 일치하는 열거 형을 찾는 도우미 클래스가 있습니다.

이렇게하면 단일 열거에 여러 매핑을 가질 수 있습니다.

public enum Age
{
    [Metadata("Value", "New_Born")]
    [Metadata("Value", "NewBorn")]
    New_Born = 1,
    [Metadata("Value", "Toddler")]
    Toddler = 2,
    [Metadata("Value", "Preschool")]
    Preschool = 4,
    [Metadata("Value", "Kindergarten")]
    Kindergarten = 8
}

이런 내 도우미 클래스로

public static class MetadataHelper
{
    public static string GetFirstValueFromMetaDataAttribute<T>(this T value, string metaDataDescription)
    {
        return GetValueFromMetaDataAttribute(value, metaDataDescription).FirstOrDefault();
    }

    private static IEnumerable<string> GetValueFromMetaDataAttribute<T>(T value, string metaDataDescription)
    {
        var attribs =
            value.GetType().GetField(value.ToString()).GetCustomAttributes(typeof (MetadataAttribute), true);
        return attribs.Any()
            ? (from p in (MetadataAttribute[]) attribs
                where p.Description.ToLower() == metaDataDescription.ToLower()
                select p.MetaData).ToList()
            : new List<string>();
    }

    public static List<T> GetEnumeratesByMetaData<T>(string metadataDescription, string value)
    {
        return
            typeof (T).GetEnumValues().Cast<T>().Where(
                enumerate =>
                    GetValueFromMetaDataAttribute(enumerate, metadataDescription).Any(
                        p => p.ToLower() == value.ToLower())).ToList();
    }

    public static List<T> GetNotEnumeratesByMetaData<T>(string metadataDescription, string value)
    {
        return
            typeof (T).GetEnumValues().Cast<T>().Where(
                enumerate =>
                    GetValueFromMetaDataAttribute(enumerate, metadataDescription).All(
                        p => p.ToLower() != value.ToLower())).ToList();
    }

}

그런 다음 다음과 같이 할 수 있습니다.

var enumerates = MetadataHelper.GetEnumeratesByMetaData<Age>("Value", "New_Born");

완전성을 위해 여기에 속성이 있습니다.

 [AttributeUsage(AttributeTargets.Field, Inherited = false, AllowMultiple = true)]
public class MetadataAttribute : Attribute
{
    public MetadataAttribute(string description, string metaData = "")
    {
        Description = description;
        MetaData = metaData;
    }

    public string Description { get; set; }
    public string MetaData { get; set; }
}

0

나이를 파싱하려면 :

Age age;
if (Enum.TryParse(typeof(Age), "New_Born", out age))
  MessageBox.Show("Defined");  // Defined for "New_Born, 1, 4 , 8, 12"

정의되었는지 확인하려면 :

if (Enum.IsDefined(typeof(Age), "New_Born"))
   MessageBox.Show("Defined");

Age열거 형 사용 계획에 따라 플래그 가 옳지 않을 수 있습니다. 아시다시피 [Flags]는 여러 값을 허용 할 것임을 나타냅니다 (비트 마스크에서와 같이). 여러 값이 있기 때문에 IsDefinedfalse를 반환 Age.Toddler | Age.Preschool합니다.


2
확인되지 않은 입력이므로 TryParse를 사용해야합니다 .
Servy

1
MessageBox는 웹 환경에서 실제로 의미가 없습니다.
Servy
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.