dev*_*xer 5 c# generics enums casting nullable
我有一个枚举,Foo
:
public enum Foo { Alpha, Bravo, Charlie }
Run Code Online (Sandbox Code Playgroud)
如果我尝试从盒装int
到下面的演员Foo?
,我得到一个InvalidCastException
:
var x = (Foo?)(object)1;
Run Code Online (Sandbox Code Playgroud)
这让我进行了一些实验......
var x = (Foo)(object)1; // succeeds
var x = (long)(object)1; // fails
var x = (long?)(object)1; // fails
var x = (long)1; // succeeds
var x = (long?)1; // succeeds
var x = (int)(object)1; // succeeds
var x = (int?)(object)1; // succeeds
Run Code Online (Sandbox Code Playgroud)
这告诉我的是你可以从盒装int
到枚举而不是a long
,你不能从盒装转换int
为任何类型的可以为空的除外int?
.
顺便说一句,我首先要把它int
放到object
第一位的原因是我真的试图从int
一个泛型参数转换成一个泛型参数TValue
,如下所示:
var x = (TValue)(object)1;
Run Code Online (Sandbox Code Playgroud)
如果我没有(object)
,它将无法编译.(有关详细信息,请参阅Eric Lippert撰写的此博客文章.)
问题
为什么你可以从盒装int
转换为枚举,但不能转换为可空的枚举(而不是a long
或a long?
)?
什么是最简单的重写方式,var x = (TValue)(object)1;
以便它可以编译,在运行时工作,并且具有高性能(假设TValue
确定是Foo?
在运行时)?
要回答第一个问题,只有当盒装值是枚举的基础类型时,才能从盒装值转换为枚举值.如果你宣布
enum Foo : byte { ...
Run Code Online (Sandbox Code Playgroud)
你将无法从盒装int转换为Foo.
要回答第二个问题,请尝试
var x = (TValue)Enum.ToObject(typeof(TValue), 1);
Run Code Online (Sandbox Code Playgroud)
这涉及拳击; 如果你需要一个不会打包的解决方案,那将会更复杂.