接受枚举项并返回枚举值(而不是索引)的C#函数。

4

假设我有以下声明:

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

这个可重复使用的函数应该长什么样?
谢谢! -ren
6个回答

15

修订后的答案(在澄清问题后)

不,没有比强制转换更干净的方法了。相比于方法调用,它更具信息性、更便宜、更短等等。这是你能想到的最低影响。

请注意,如果您想编写一个通用方法来进行转换,那么您还需要指定要将其转换为什么:例如,枚举可以基于 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,但我希望能更干净地编码。 - ren
1
你说得对。这是个愚蠢的想法。我在构建 EnumHelper 类时有些冲动了。 - ren

8

您可以通过强制类型转换来获取枚举的整数值:

int complexityValueToStore = (int)Complexity.Normal;

4
我知道的最通用的方法是使用反射读取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#编译器上进行了测试。很遗憾,似乎没有内置的方法来做到这一点。

2
我知道这不是你要求的内容,但这可能是你会喜欢的。
我发现如果你知道枚举的最小值,你可以在没有强制转换的情况下找到枚举的整数值:
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;

我认为这种技术比强制类型转换为整数更具美感。

我不确定如果你基于byte或long创建枚举会发生什么 - 我猜测你会得到byte或long的差异值。


这也假设枚举值是连续的(是这个词吗?),并从已知值开始,并按正确顺序排列。尝试 enum DealBreaker { First=3, Second=1, Third=19 }。哦,而且枚举没有 [Flags] 属性。 - Benjol

0

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

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

然而,第二个选项有点违背了枚举的初衷 - 你试图拥有离散的值而不是列表和索引。如果这正是你想要的,我建议重新考虑你的需求。


0

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

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

这对我有效。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接