簡體   English   中英

將整數轉換為僅在運行時已知的盒裝枚舉類型

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

想象一下,我們有一個枚舉:

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和unbox作為int包裝,或者將框作為int和unbox作為Foo非常開心)

然而 (問題); 如果枚舉類型僅在運行時已知,那么事情就更棘手了。 把它當作一個int顯然是微不足道的 - 但是我可以把它當作Foo嗎? (理想情況下,不使用泛型和MakeGenericMethod ,這將是丑陋的)。 Convert.ChangeType拋出異常。 ToStringEnum.Parse有效,但效率非常低。

我可以查看定義的值( Enum.GetValuesType.GetFields ),但這對[Flags]來說非常難,即使沒有,也需要首先返回底層類型(謝天謝地,這並不難) 。

但; 是否更直接從正確的底層類型的值獲取到枚舉類型的框,其中類型僅在運行時已知?

我認為Enum.ToObject方法會做你想要的。

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

只是想在@ aaronb的答案中添加一些內容:我必須為某些自動映射代碼執行此操作,並發現我需要進行多項檢查才能使代碼適用於任意類型。 特別是,null值和可空的枚舉會讓你頭疼。

我目前最簡單的代碼是:

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

如果你永遠不能擁有可空類型,那么就忽略它。 :)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM