【问题标题】:C# function that accepts an Enum item and returns the enum value (not the index)接受枚举项并返回枚举值(不是索引)的 C# 函数
【发布时间】:2009-03-27 00:17:47
【问题描述】:

假设我有以下声明:

public enum Complexity { Low = 0, Normal = 1, Medium = 2,  High = 3 }
public enum Priority { Normal = 1, Medium = 2,  High = 3, Urgent = 4 }

我想对其进行编码,以便获得枚举值(不是索引,就像我之前提到的那样):

//should store the value of the Complexity enum member Normal, which is 1
int complexityValueToStore = EnumHelper.GetEnumMemberValue(Complexity.Normal); 
//should store the value 4
int priorityValueToStore = EnumHelper.GetEnumMemberValue(Priority.Urgent); 

这个可重用的函数应该是什么样子的?

蒂亚! -人

【问题讨论】:

    标签: c# function enums generics


    【解决方案1】:

    修改后的答案(问题澄清后)

    不,没有什么比演员表更干净的了。它比方法调用提供更多信息、更便宜、更短等。它的影响与您希望的一样低。

    请注意,如果您想编写一个通用方法来进行转换,您还必须指定要将其转换为什么:例如,枚举可以基于bytelong。通过输入演员表,您明确说出要将其转换为的内容,然后它就会执行此操作。

    原答案

    “索引”到底是什么意思?你的意思是数值吗?只需投到int。如果您的意思是“枚举中的位置”,则必须确保值按数字顺序排列(因为这是 Enum.GetValues 给出的 - 不是声明顺序),然​​后执行:

    public static int GetEnumMemberIndex<T>(T element)
        where T : struct
    {
        T[] values = (T[]) Enum.GetValues(typeof(T));
        return Array.IndexOf(values, element);
    }
    

    【讨论】:

    • 我的意思是数值。我知道我可以转换为 int,但我希望我可以更清晰地编码它
    • 你是对的。这是一个愚蠢的想法。我在构建 EnumHelper 类时被带走了。
    【解决方案2】:

    您可以通过强制转换找到枚举的整数值:

    int complexityValueToStore = (int)Complexity.Normal;
    

    【讨论】:

      【解决方案3】:

      我知道的最通用的方法是使用反射读取value__ 字段。 这种方法不对枚举的底层类型做任何假设,因此它适用于不基于Int32 的枚举。

      public static object GetValue(Enum e)
      {
          return e.GetType().GetField("value__").GetValue(e);
      }
      
      Debug.Assert(Equals(GetValue(DayOfWeek.Wednesday), 3));                //Int32
      Debug.Assert(Equals(GetValue(AceFlags.InheritOnly), (byte) 8));        //Byte
      Debug.Assert(Equals(GetValue(IOControlCode.ReceiveAll), 2550136833L)); //Int64
      

      注意:我只使用 Microsoft C# 编译器对此进行了测试。很遗憾,似乎没有内置的方法来做到这一点。

      【讨论】:

        【解决方案4】:

        我知道这不是您要求的,但您可能会喜欢它。

        我发现如果你知道枚举的最小值是多少,你可以在没有强制转换的情况下找到枚举的整数值:

        public enum Complexity { Low = 0, Normal = 1, Medium = 2,  High = 3 }
        
        int valueOfHigh = Complexity.High - Complexity.Low;
        

        这不适用于优先级,除非您添加了一些最小值 0,或者添加了 1:

        public enum Priority { Normal = 1, Medium = 2,  High = 3, Urgent = 4 }
        
        int valueOfUrgent = Priority.Urgent - Priority.Normal + 1;
        

        我发现这种技术在美学上比强制转换为 int 更具吸引力。

        我不确定如果你有一个基于字节或长的枚举会发生什么 - 我怀疑你会得到字节或长的差异值。

        【讨论】:

        • 这也假设枚举值是连续的(是这个词吗?),并且从一个已知值开始,并且顺序正确。试试enum DealBreaker { First=3, Second=1, Third=19 }。哦,枚举没有 [Flags] 属性。
        【解决方案5】:

        如果你想要这个值,你可以将枚举转换为 int。这将设置 complexValueToStore == 1 和 priorityValueToStore == 4。

        如果您想获取索引(即:Priority.Urgent == 3),您可以使用Enum.GetValues,然后只需在该列表中找到您当前枚举的索引即可。但是,返回的列表中枚举的顺序可能与您的代码中的不同。

        但是,第二种选择首先违背了 Enum 的目的 - 您试图使用离散值而不是列表和索引。如果这是您想要的,我会重新考虑您的需求。

        【讨论】:

          【解决方案6】:

          这是解决问题的最简单方法:

          public static void GetEnumMemberValue<T>(T enumItem) where T : struct 
          {
              return (int) Enum.Parse(typeof(T), enumItem.ToString());
          }
          

          它对我有用。

          【讨论】:

            猜你喜欢
            • 2023-04-10
            • 1970-01-01
            • 1970-01-01
            • 2011-12-16
            • 1970-01-01
            • 1970-01-01
            • 2019-12-23
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多