How would I convert a int to enum value at runtime

2020-07-27 04:26发布

What I have is a string variable that is the name of a enum. I have the integer of the enum. How would I convert that into instance of the enum itself?

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

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

I see many posts that require you to have an instance of the enum to get it's like this highly upvoted answer.

I need to do this at runtime.

Edit: I am trying to write a class that gets and sets settings in an api that has hundreds of enums that represent settings.

The enums break are categorized by 5 basic setting types represented by five enums. These enums are like:

DoubleValueEnum
IntegerValueEnum
BooleanValueEnum
StringValueEnum

These enums are pointers to settings of type double, integer, string, bool. I believe that underneath the hood they have a database that keeps a table like this:

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

For doubles there is no "lower" enum that it is pointing to. For integer there is a deeper enum like "PenNumber.Red = 1, PenColor.Green = 2.

Hypothetical pen color:

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

Each of these enums have hundreds of values. Each of these enums has a prewritten function the gets or sets the enum:

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)

Real example:

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

2条回答
家丑人穷心不美
2楼-- · 2020-07-27 04:45

It looks like you are trying to use BitWise operations on Enum values to allow a single setting property to represent multiple optional states.

For this sir Enums have support built in if you use the Flags attribute:
There is a good SO dicussion that covers this too: What does the [Flags] Enum Attribute mean in C#?

Lets look at PenColor enum first:

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

By defining the discrete enums with base-2 values, we can now use either bitwise operations on the PenColor enum, or we can use simple integer addition/subtraction:

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

All of those statements will be equivalent. So potentially this syntax replaces your SetIntegerValueEnum, but it relies on the enum definition being implemented with base-2 values.

To test, this statement should be true:

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

The last option will only work if the [Flags] attribute decorates the enum type definition.

You can then use this in switching logic or comparisons

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);
查看更多
冷血范
3楼-- · 2020-07-27 04:55

For your given enum definition:

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

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

Use Enum.Parse(Type, string) to parse the string value as an Enum value.

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

However, you need to know they type of the Enum definition that you want to parse. If the exact type of the enum value is unknown, but you do know the potential types, then you can iterate through the types and test using the 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))

If you do not know the specific type of the enum but you do know the class name, you can use the Type.GetType Method to resolve the type

For this to work you do need to know the full namespace of type that you want to resolve, AND the assembly that the type is defined in must already be loaded.

The syntax to convert an int to an enum is discussed here: https://stackoverflow.com/a/56859286/1690217

In this example, we know that all of the enums reside in the API.Client.Enums namespace:

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

Usually we do not need to bother with a lot of this conversion just to pass values between systems, the fact that the enum resolves to an integer means that for unknown types we should be able to write our logic to just deal with the integer, and only convert it back to a specific enum when you need it.

查看更多
登录 后发表回答