简体   繁体   English

将整数转换为仅在运行时已知的盒装枚举类型

[英]Converting an integer to a boxed enum type only known at runtime

Imagine we have an enum: 想象一下,我们有一个枚举:

enum Foo { A=1,B=2,C=3 }

If the type is known at compile-time, a direct cast can be used to change between the enum-type and the underlying type (usually int ): 如果在编译时已知类型,则可以使用直接强制转换来在枚举类型和基础类型之间进行更改(通常为int ):

static int GetValue() { return 2; }
...
Foo foo = (Foo)GetValue(); // becomes Foo.B

And boxing this gives a box of type Foo : 而拳击这给了一个Foo类型的盒子:

object o1 = foo;
Console.WriteLine(o1.GetType().Name); // writes Foo

(and indeed, you can box as Foo and unbox as int , or box as int and unbox as Foo quite happily) (实际上,你可以将Foo和unbox作为int包装,或者将框作为int和unbox作为Foo非常开心)

However (the problem); 然而 (问题); if the enum type is only known at runtime things are... trickier. 如果枚举类型仅在运行时已知,那么事情就更棘手了。 It is obviously trivial to box it as an int - but can I box it as Foo ? 把它当作一个int显然是微不足道的 - 但是我可以把它当作Foo吗? (Ideally without using generics and MakeGenericMethod , which would be ugly). (理想情况下,不使用泛型和MakeGenericMethod ,这将是丑陋的)。 Convert.ChangeType throws an exception. Convert.ChangeType抛出异常。 ToString and Enum.Parse works, but is horribly inefficient. ToStringEnum.Parse有效,但效率非常低。

I could look at the defined values ( Enum.GetValues or Type.GetFields ), but that is very hard for [Flags] , and even without would require getting back to the underlying-type first (which isn't as hard, thankfully). 我可以查看定义的值( Enum.GetValuesType.GetFields ),但这对[Flags]来说非常难,即使没有,也需要首先返回底层类型(谢天谢地,这并不难) 。

But; 但; is there a more direct to get from a value of the correct underlying-type to a box of the enum-type, where the type is only known at runtime? 是否更直接从正确的底层类型的值获取到枚举类型的框,其中类型仅在运行时已知?

I think the Enum.ToObject method will do what you want. 我认为Enum.ToObject方法会做你想要的。

Type type= typeof(Foo);
object o1 = Enum.ToObject(type,GetValue());

Just wanted to add something to @aaronb's answer : I had to do this very thing for some auto-mapping code and found out that I needed to do several checks in order to make the code work for arbitrary types. 只是想在@ aaronb的答案中添加一些内容:我必须为某些自动映射代码执行此操作,并发现我需要进行多项检查才能使代码适用于任意类型。 In particular, null values and nullable enums will give you headaches. 特别是,null值和可空的枚举会让你头疼。

The most foolproof code I have at the moment is this: 我目前最简单的代码是:

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

If you can never have a nullable type then just ignore this. 如果你永远不能拥有可空类型,那么就忽略它。 :) :)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 将字符串转换为枚举,但枚举类型仅在运行时已知 - Convert string to enum, but when enum type is only known at runtime 如果只在运行时知道枚举类型,如何枚举枚举? - How to enumerate enums when the enum type is only known at runtime? 将FormCollection转换为仅在运行时已知的类型的对象 - Convert FormCollection to object of type known only at runtime 动态对象强制转换为仅在运行时已知的类型 - Dynamic object cast to type known at runtime only 动态调度按类型仅在运行时已知 - Dynamic dispatch by Type only known at runtime 装箱的可为空的基础类型可以强制转换为枚举,但装箱的枚举类型不能强制转换为可空类型 - Boxed nullable underlying type can be cast to enum but boxed enum type can't be cast to nullable type 如何将ProjectTo从基类型转换为仅在运行时已知的类型? - How to ProjectTo from a base type to a type only known at runtime? 我可以实现泛型类型并将其传递给仅在运行时才知道的类型吗? - Can I implement a generic type and pass it a type that is known only at runtime? 将对象转换为仅在运行时已知的类型变量 - Casting object to type into variable of said type known only at runtime 在 Saga 中发布消息,其中类型仅在运行时已知 - Publish message in Saga where type is known only runtime
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM