当我有一个字符串和一个整数时,如何在运行时将int转换为枚举值?

2020-02-22 c# reflection enums

我所拥有的是一个字符串变量,它是一个枚举的名称。我有枚举的整数。我如何将其转换为枚举本身的实例?

Enum TestEnum
    {
        One = 1,
        Two = 2,
        Three = 3
    }

string str = "TestEnum";
int intValue = 2;

我看到许多帖子都要求您有一个枚举实例才能获得此高度赞同的答案

我需要在运行时执行此操作。

编辑 : 我正在尝试编写一个类,该类在具有数百个代表设置的枚举的api中获取和设置设置。

枚举中断由5个枚举表示的5种基本设置类型进行分类。这些枚举就像:

DoubleValueEnum
IntegerValueEnum
BooleanValueEnum
StringValueEnum

这些枚举是指向double,integer,string,bool类型的设置的指针。我相信在幕后他们有一个数据库,里面保存着一个这样的表:

Type    key    value      Represents
------- ------ -------    ---------------------------------
Double  23     2.745      DoubleValueEnum.DrawingWidth
Integer 5      18         IntegerValueEnum.PenColor
Double  54     15.9245    DoubleValueEnum.GridMajorSpacing

对于双打,没有指向的“下级”枚举。对于整数,存在更深的枚举,例如“ PenNumber.Red = 1,PenColor.Green = 2。

假设的笔颜色:

Enum PenColor
{
    Red = 1,
    Blue = 2,
}

这些枚举中的每一个都有数百个值。这些枚举都有一个预先编写的函数,用于获取或设置枚举:

GetDoubleEnumValue(int, option)
GetIntegerValueEnum(int, option)
GetBooleanValueEnum(int, option)
GetStringValueEnum(int, option)

SetXXXXXEnumValue(enum, value)
SetDoubleEnumValue(int, int)
SetIntegerValueEnum(int, int)
SetBooleanValueEnum(int, int)
SetStringValueEnum(int, int)

真实的例子:

SetIntegerValueEnum ((int)IntegerValueEnum.swDxfVersion, (int)swDxfFormat_e.swDxfFormat_R14);

Answers

对于给定的枚举定义:

enum TestEnum
{
    One = 1,
    Two = 2,
    Three = 3
}

enum TestEnum2
{
    OnePoint1 = 1,
    OnePoint2 = 2,
    OnePoint3 = 3
}

使用Enum.Parse(Type,string)将字符串值解析为Enum值。

string str = "Two";
TestEnum valueAsEnum = (TestEnum)Enum.Parse(typeof(TestEnum), str);

但是,您需要知道它们要解析的Enum定义的类型 。如果枚举值的确切类型是未知的,但您确实知道潜在的类型,则可以遍历类型并使用Enum.TryParse进行测试。

string str = "Two";
object enumValue = null;

if (!Enum.TryParse(typeof(TestEnum), str, true, out enumValue))
    Enum.TryParse(typeof(TestEnum2), str, true, out enumValue))

如果您不知道枚举的特定类型,但是您知道类名,则可以使用Type.GetType方法来解析类型。

对于这个工作,你需要知道类型的完整的命名空间要解决, 以及组件类型中必须定义已经被加载。

此处讨论了将int转换为枚举的语法: https : //stackoverflow.com/a/56859286/1690217

在此示例中,我们知道所有枚举都位于API.Client.Enums命名空间中:

string str = "TestEnum";
int intValue = 2;

string ns = "API.Client.Enums";
Type enumType = Type.GetType($"{ns}.{str}");

// now we can parse the value:
object value = Enum.ToObject(enumType, (object)intValue);

通常,我们不必为了在系统之间传递值而烦恼大量这种转换,因为枚举解析为整数这一事实意味着对于未知类型,我们应该能够编写逻辑来处理整数,并且仅在需要时才将其转换回特定的枚举

似乎您正在尝试对Enum值使用BitWise操作,以允许单个设置属性表示多个可选状态。

为此,如果您使用Flags属性, Enums将内置支持:
有一个很好的SO讨论也涵盖了这一点: [Flags] Enum属性在C#中是什么意思?

首先让我们看一下PenColor枚举:

[Flag]
enum PenColor : int
{
    None = 0        // 0
    Red = 1 << 0,   // 1
    Green = 1 << 1, // 2
    Blue = 1 << 2   // 4
}

通过使用base-2值定义离散枚举,我们现在可以对PenColor枚举使用按位运算,也可以使用简单的整数加/减:

PenColor cyan = PenColor.Green | PenColor.Blue;
int cyanInt = (int)PenColor.Green + (int)PenColor.Blue;
PenColor cyanCasted = (PenColor)cyanInt;

所有这些陈述都是等效的。因此,该语法可能会替换您的SetIntegerValueEnum ,但它依赖于以base-2值实现的枚举定义

为了测试,此语句应为true:

SetIntegerValueEnum ((int)IntegerValueEnum.swDxfVersion, (int)swDxfFormat_e.swDxfFormat_R14)  
== (int)IntegerValueEnum.swDxfVersion + (int)swDxfFormat_e.swDxfFormat_R14)  
== IntegerValueEnum.swDxfVersion | swDxfFormat_e.swDxfFormat_R14

仅当[Flags]属性修饰枚举类型定义时,最后一个选项才有效。

然后,您可以在切换逻辑或比较中使用它

PenColor cyan = PenColor.Green | PenColor.Blue;
bool hasBlue = cyan & PenColor.Blue == PenColor.Blue;
// you can also use the slower Enum.HasFlag
hasBlue = cyan.HasFlag(PenColor.Blue);

Related