5

我有一个枚举,Foo

public enum Foo { Alpha, Bravo, Charlie }

如果我尝试从 boxedint到 a进行以下转换Foo?,我会得到InvalidCastException

var x = (Foo?)(object)1;

这让我做了一些实验......

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

这告诉我的是,您可以从 boxedint转换为 enum 但不能转换为 a long,并且您不能从 boxed 转换为int除 an 之外的任何类型的可为空值int?

顺便说一句,我将intto objectfirst 转换为第一个的原因是我真的想从 anint转换为 generic parameter TValue,如下所示:

var x = (TValue)(object)1;

如果我没有(object),它将无法编译。(有关详细信息,请参阅Eric Lippert的这篇博文。)

问题

  1. 为什么可以从盒装转换int为枚举,但不能转换为可为空的枚举(也不能转换为 along或 a long?)?

  2. 什么是最简单的重写方法,var x = (TValue)(object)1;以便它编译,在运行时工作,并且是高性能的(假设在运行时TValue被确定为 a Foo?)?

4

2 回答 2

5

要回答第一个问题,只有当装箱值是枚举的基础类型时,才可以将装箱值转换为枚举。如果你宣布

enum Foo : byte { ...

您将无法从 boxed int 转换为 Foo。

要回答第二个问题,请尝试

var x = (TValue)Enum.ToObject(typeof(TValue), 1);

不过,这涉及拳击;如果您需要一个不会装箱的解决方案,它会更加复杂。

于 2012-09-06T00:15:23.690 回答
1

Nullables 不是原子类型的某种特殊类别,而是 type 的简写Nullable<T>,这就是为什么您不能将装箱的 int 强制转换为可为空的枚举的原因。如果你想创建一个可为空的枚举,你可以这样做:

var x = new Nullable<Foo>((Foo)1);

我想这回答了你的两个问题!

于 2012-09-05T23:51:09.530 回答