使用反射在C#中创建具有字符串值的未知枚举实例

14

我有一个问题,无法确定如何在运行时创建枚举的实例。我已经获取了枚举的System.Type并检查了BaseType是否为System.Enum。我的值是一个int值,匹配神秘枚举中的项。

到目前为止,我所拥有的代码仅仅是上述逻辑,如下所示。

        if (Type.GetType(type) != null)
        {
            if (Type.GetType(type).BaseType.ToString() == "System.Enum")
            {
                return ???;
            }
        }

在以往使用枚举类型时,我通常在编码时就知道我要解析哪个枚举值。但在当前情况下,我感到困惑,并且在使用谷歌搜索时没有找到有用的答案。我通常会做这样的事情:

When working with Enums in the past i have always know at code time which enum i am trying to parse but in this scenario im confused and have had little luck articulating my question in a google friendly way... I would usually do something like

(SomeEnumType)int

但由于我在编写代码时不知道EnumType,我该如何实现相同的功能?


有点困惑你在 "return ???" 后想做什么,以及为什么这种情况下需要反射。你仍然可以使用 (SomeEnumType)type 来将类型转换为 SomeEnumType。 - outcoldman
问题是我不知道可能是哪个枚举,在运行时它可能是任何一个。返回的代码应该类似于:[code] Enum.Parse(Type.GetType(type), ob);[/code] - Jarmez De La Rocha
这行代码 Type.GetType(type).BaseType.ToString() == "System.Enum" 告诉我对象 type 已经是你的 SomeEnumType 类型,那么为什么需要将它从 SomeEnumType 转换成 SomeEnumType?你能否提供更多背景信息,说明你想要实现什么? - outcoldman
是的,实际上那就解决了问题,我自己回答了我的问题。顺便说一下,我正在使用包含系统类型字符串和以int形式表示的值的数据行来创建所需枚举的实例。感谢你的帮助 :) - Jarmez De La Rocha
2个回答

20

使用Enum类上的ToObject方法:

var enumValue = Enum.ToObject(type, value);

或者像你提供的代码一样:

if (Type.GetType(type) != null)
{
    var enumType = Type.GetType(type);
    if (enumType.IsEnum)
    {
        return Enum.ToObject(enumType, value);
    }
}

1
不必写成 enumType.BaseType == typeof(Enum),直接写成 enumType.IsEnum 更简单(而且可能等价)。 - Jeppe Stig Nielsen
你为什么放弃了 Enum.ToObject 方法呢?我更喜欢它而不是像现在这样使用 string 实例。 - Jeppe Stig Nielsen

1

使用(ENUMName)Enum.Parse(typeof(ENUMName), integerValue.ToString())作为一个通用函数(已编辑以纠正语法错误)...

    public static E GetEnumValue<E>(Type enumType, int value) 
                        where E : struct
    {
        if (!(enumType.IsEnum)) throw new ArgumentException("Not an Enum");
        if (typeof(E) != enumType)
            throw new ArgumentException(
                $"Type {enumType} is not an {typeof(E)}");
        return (E)Enum.Parse(enumType, value.ToString());
    }

旧的错误版本:

public E GetEnumValue(Type enumType, int value) where E: struct
{
  if(!(enumType.IsEnum)) throw ArgumentException("Not an Enum");
  if (!(typeof(E) is enumType)) 
       throw ArgumentException(string.format(
           "Type {0} is not an {1}", enumType, typeof(E));
  return Enum.Parse(enumType, value.ToString());
}

2
这个方法有几个问题。(1)你的方法有一个where约束,但是你忘记“定义”类型E并使你的方法成为泛型。(2)当调用该方法时,应该如何提供E?编译器不会自动推断。(3)is表达式的语法错误。is的右侧是一个对象,而不是一个类型。也许你想使用!=代替is?目的是什么?(4)返回类型要求你将输出从非泛型的Enum.Parse方法转换。 - Jeppe Stig Nielsen
抱歉,没有进行编译检查的打字。已经编辑以修复语法错误。 - Charles Bretana

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