想象一下,我们有一个枚举:
enum Foo { A=1,B=2,C=3 }
如果在编译时已知类型,则可以使用直接强制转换来在枚举类型和基础类型之间进行更改(通常为int
):
static int GetValue() { return 2; }
...
Foo foo = (Foo)GetValue(); // becomes Foo.B
拳击会给出一个Foo
类型的框:
object o1 = foo;
Console.WriteLine(o1.GetType().Name); // writes Foo
(实际上,您可以将Foo
打开并将其打包为int
,或将框打包为int
,将打开的广告框设置为Foo
非常高兴)
然而 (问题);如果枚举类型仅在运行时已知,那么事情就更棘手了。将其格式化为int
显然是微不足道的 - 但是我可以将其设为Foo
吗? (理想情况下不使用泛型和MakeGenericMethod
,这将是丑陋的)。 Convert.ChangeType
抛出异常。 ToString
和Enum.Parse
有效,但可能效率低下。
我可以查看已定义的值(Enum.GetValues
或Type.GetFields
),但这对[Flags]
非常困难,即使没有,也需要先返回基础类型(这不是那么难,谢天谢地。)
但;是否更直接从正确的底层类型的值获取到枚举类型的框,其中类型仅在运行时已知?
答案 0 :(得分:70)
我认为Enum.ToObject
方法会做你想要的。
Type type= typeof(Foo);
object o1 = Enum.ToObject(type,GetValue());
答案 1 :(得分:8)
只是想向@aaronb's answer添加一些内容:我必须对某些自动映射代码执行此操作,并发现我需要进行多项检查才能使代码适用于任意类型。特别是,空值和可空的枚举会让您头疼。
我目前最简单的代码是:
static object CastBoxedValue(object value, Type destType)
{
if (value == null)
return value;
Type enumType = GetEnumType(destType);
if (enumType != null)
return Enum.ToObject(enumType, value);
return value;
}
private static Type GetEnumType(Type type)
{
if (type.IsEnum)
return type;
if (type.IsGenericType)
{
var genericDef = type.GetGenericTypeDefinition();
if (genericDef == typeof(Nullable<>))
{
var genericArgs = type.GetGenericArguments();
return (genericArgs[0].IsEnum) ? genericArgs[0] : null;
}
}
return null;
}
如果你永远不能拥有可空类型,那么就忽略它。 :)