[英]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
拋出異常。 ToString
和Enum.Parse
有效,但效率非常低。
我可以查看定義的值( Enum.GetValues
或Type.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.