【问题标题】:how to check if string value is in the Enum list?如何检查字符串值是否在枚举列表中?
【发布时间】:2012-06-03 23:15:28
【问题描述】:

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

有没有办法检查这个字符串值 New_Born 是否在我的枚举列表中

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

我现在可以使用 if 语句,但如果我的枚举列表变得更大。我想找到更好的方法来做到这一点。我正在考虑使用 Linq,只是不知道该怎么做。

【问题讨论】:

  • Enum.IsDefined 不行吗?

标签: c# c#-4.0 c#-3.0


【解决方案1】:

你可以使用:

 Enum.IsDefined(typeof(Age), youragevariable)

【讨论】:

  • IsDefined 需要 Enum 实例检查
  • 请记住Enum.IsDefined() 区分大小写!所以这不是一个“通用解决方案”。
  • 通常不建议使用 IsDefined,因为 Is 使用反射,对 IsDefined 的调用在性能和 CPU 方面都是非常昂贵的调用。请改用 TryParse。 (从pluralsight.com学习)
【解决方案2】:

您可以使用 Enum.TryParse 方法:

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

【讨论】:

  • 这仅适用于 .NET 4
  • 这个问题是如果你提供任何整数(而不是你的“New_Born”字符串,我的意思是),它会返回true。
【解决方案3】:

你可以使用TryParse方法,如果成功则返回true:

Age age;

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

【讨论】:

    【解决方案4】:

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

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

    【讨论】:

      【解决方案5】:

      您应该使用 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
      }
      

      【讨论】:

        【解决方案6】:

        解析年龄:

        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 将为 Age.Toddler | Age.Preschool 返回 false,因为它有多个值。

        【讨论】:

        • 应该使用TryParse,因为它是未经验证的输入。
        • MessageBox 在 Web 环境中实际上没有意义。
        【解决方案7】:

        我知道这是一个旧线程,但这里有一个稍微不同的方法,它使用枚举上的属性,然后使用帮助器类来查找匹配的枚举。

        这样,您可以在单个枚举上拥有多个映射。

        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; }
        }
        

        【讨论】:

          猜你喜欢
          • 2014-08-09
          • 2020-11-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-02-12
          • 2017-03-28
          • 1970-01-01
          相关资源
          最近更新 更多