【问题标题】:Check that integer type belongs to enum member检查整数类型是否属于枚举成员
【发布时间】:2010-04-09 06:06:43
【问题描述】:

我想检查某个整数类型是否属于(一个)枚举成员。

例如,

public enum Enum1
{
    member1 = 4,

    member2 = 5,

    member3 = 9,

    member4 = 0
}

Enum1 e1 = (Enum1)4 给了我 member1

Enum1 e2 = (Enum1)10 什么也没给我,我想检查一下。

【问题讨论】:

  • 您要检查什么...?
  • 不知道你使用枚举的目的。试试你是否可以使用字典来代替
  • Validate Enum Values的可能重复

标签: c#


【解决方案1】:

使用Enum.IsDefined

Enum.IsDefined(typeof(Enum1), 4) == true

但是

Enum.IsDefined(typeof(Enum1), 1) == false

【讨论】:

  • 如果您需要速度,请不要使用它:Enum.IsDefined 使用反射并且非常很慢。
  • 首先,微优化是对编程工作的浪费。其次,Enum.IsDefined 每毫秒将运行超过 2,000 次。我不会认为那么慢。
  • @Sam:我说“如果你需要速度”。例如,如果您在网络帧处理循环中执行此操作,最终可能会得到糟糕的结果。 @Alexander Stalt:除非您一一检查每个值,否则我想您不能。但这太过分了(就代码长度而言)。真正的问题是:真的需要这样的测试吗?通常,一个处理所有可能值的 switch 语句和一个 "default" 就足够了。但我们显然缺乏在这里讨论的信息(这可能是题外话)
  • 所以编写设计糟糕/未优化的代码是可以的,因为 C# 是 slow 反正?我倾向于同意这样一个事实,即微优化通常不会像成本那么高。但是当它真的需要时避免反射是不是编程工作的浪费。 2000 次/毫秒(在我们不知道规格的您的 计算机上)对于像 32/64 位匹配过程这样简单的事情来说是慢。然而我承认,在这种情况下(并且在大多数情况下),这并不重要。
  • 对不起,如果我以某种方式冒犯了您,警告 OP 您的方法在某些特定情况下可能会很慢。我同意你的回答!然而,高效的编码有时需要写几行代码:并非所有事情都可以在一次调用中完成;)如果 OP 不需要非常高的性能并且更喜欢代码简单,那么您的解决方案是 完美。这就是我在第三条评论中所说的。我自己经常使用Enum.IsDefined 方法,但在某些特定情况下我不会。无论如何,OP接受了你的答案(我什至赞成)所以......;)
【解决方案2】:

正如 Sam 所说,您可以使用 IsDefined。不过这有点尴尬。你可能想看看我的Unconstrained Melody库,它会让你:

Enum1 e2 = (Enum1)10;
if (e2.IsNamedValue()) // Will return false
{
}

单个枚举调用可能不值得,但如果您使用枚举做很多事情,您可能会在其中找到一些有用的东西。

它应该比Enum.IsDefined btw 更快。它目前只进行线性扫描,但如果您需要改进它,请告诉我:) (大多数枚举足够小,它们可能不会从HashSet 中受益,但我们可以进行二进制搜索。 ..)

【讨论】:

    【解决方案3】:
    int testNum = 5;
    bool isMember = Enum.GetValues(typeof(Enum1)).Cast<int>().Any(x => x == testNum);
    

    【讨论】:

      【解决方案4】:

      您查看枚举的值并将它们与整数进行比较。

          static bool EnumTest(int testVal, Enum e)
          {
              bool result = false;
              foreach (var val in Enum.GetValues(typeof(Enum1)))
              {
                  if ((int)val == testVal)
                  {
                      result = true;
                      break;
                  }
              }
              return result;
          }
      

      编辑:看起来 Sam 有一个 better solution。

      【讨论】:

        【解决方案5】:

        您可以使用 Enum.GetValues 来获取所有定义的值。然后检查您的值是否存在于该列表中。
        http://msdn.microsoft.com/en-us/library/system.enum.getvalues.aspx

        【讨论】:

          【解决方案6】:

          请注意,如果您有 3 个(苹果和梨)的枚举,上述方法将无法检测到它是有效的。

          [Flags]
          public enum Fruit
          { 
          
              Apples=1,
          
              Pears=2,
          
              Oranges =4,
          
          }
          

          【讨论】:

            【解决方案7】:

            这是我几年前写的一个扩展方法中的一个简洁的小 sn-p。将 TryParse 与 IsDefined 相结合,一举完成所有操作并处理枚举中不存在的值。

            if (value != null)
            {
                TEnum result;
                if (Enum.TryParse(value.ToString(), true, out result))
                {
                    // since an out-of-range int can be cast to TEnum, double-check that result is valid
                    if (Enum.IsDefined(typeof(TEnum), result.ToString() ?? string.Empty))
                    {
                        return result;
                    }
                }
            }
            

            这是整数值的扩展

            public static TEnum ParseToEnum<TEnum>(this int value, TEnum? defaultValue = null, bool useEnumDefault = false) where TEnum : struct
            {
                return ParseToEnumInternal(value, defaultValue, useEnumDefault);
            }
            

            还有一种用法

            public enum Test
            {
                Value1 = 1,
                Value2 = 3
            }
                
            var intValue = 1;
            var enumParsed = intValue.ParseToEnum<Test>(); // converts to Test.Value1
            intValue = 2;
            enumParsed = intValue.ParseToEnum<Test>(); // either throws or converts to supplied default
            enumParsed = 3.ParseToEnum<Test>(); // converts to Test.Value2
            

            有些人不喜欢它如何悬挂在(可能为空的)值的末尾,但我有一个扩展可以处理可空类型(int?)的空值,我自己喜欢它,所以 ...

            如果您有兴趣,我可以发布带有所有重载的整个扩展方法的要点。

            【讨论】:

              【解决方案8】:

              用途:

              if (Enum.IsDefined(typeof(Fruit),e2))
              {
                 //Valid Value
              }
              else
              {
                 //Invalid ENum Value
              }
              

              【讨论】:

              • 这如何添加到Samuel Neff 的accepted answer,这表明,使用Enum.IsDefined:Enum.IsDefined(typeof(Enum1), 4) == true?
              • 我展示了一种不同的方式来回答这个原始帖子的问题:“检查整数类型是否属于枚举成员”。我没有看到任何人发布此问题的回复。我认为这是最干净的方法,并且可以准确地知道整数是否在枚举中。
              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2011-12-24
              • 2013-03-20
              • 1970-01-01
              • 2018-06-16
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多