如何检查字符串值是否在Enum列表中?


91

在我的查询字符串中,我有一个age变量 ?age=New_Born

有没有一种方法可以检查此字符串值New_Born是否在我的枚举列表中

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

我现在可以使用if语句,但是如果我的Enum列表变大。我想找到一种更好的方法。我正在考虑使用Linq,只是不确定如何去做。


2
Enum.IsDefined不好?
嬉皮2012年

Answers:


153

您可以使用:

 Enum.IsDefined(typeof(Age), youragevariable)

IsDefined要求枚举实例进行检查
Viacheslav Smityukh,2012年

9
请记住,这Enum.IsDefined()是区分大小写的!因此,这不是“通用解决方案”。
柴郡猫

6
通常建议不要使用IsDefined,因为Is使用反射,因此对IsDefined的调用在性能和CPU方面都是非常昂贵的调用。改用TryParse。(从pluralsight.com获悉)
Guo

40

您可以使用Enum.TryParse方法:

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

5
仅从.NET 4开始可用
Gary Richter

2
问题是如果您提供ANY整数(不是我的“ New_Born”字符串),它将返回true。
罗曼·文森特

10

您可以使用TryParse方法,如果成功,该方法将返回true:

Age age;

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

2

我有一个使用TryParse的便捷扩展方法,因为IsDefined区分大小写。

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]表示您要允许多个值(如位掩码中所示)。 IsDefined将返回false,Age.Toddler | Age.Preschool因为它具有多个值。


2
应该使用TryParse,因为它是未经验证的输入。
Servy

1
在Web环境中,MessageBox确实没有任何意义。
Servy
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.