【问题标题】:InvalidCastException trying to cast from a boxed int to a nullable enumInvalidCastException 试图从装箱的 int 转换为可为空的枚举
【发布时间】:2012-09-05 23:44:24
【问题描述】:

我有一个枚举,Foo:

public enum Foo { Alpha, Bravo, Charlie }

如果我尝试从框选的intFoo? 进行以下转换,我会得到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

这告诉我的是,您可以从装箱的 int 转换为枚举,但不能转换为 long,并且您不能从装箱的 int 转换为任何类型的除了 int? 之外可以为空。

顺便说一句,我首先将int 转换为object 的原因是我真的想从int 转换为通用参数TValue,如下所示:

var x = (TValue)(object)1;

如果我没有(object),它将无法编译。 (详情请参阅blog post by Eric Lippert。)

问题

  1. 为什么你可以从一个装箱的int 转换为一个枚举,而不是一个可以为空的枚举(而不是一个long 也不是一个long?)?

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

    李>

【问题讨论】:

    标签: c# generics casting enums nullable


    【解决方案1】:

    要回答第一个问题,只有当装箱值是枚举的基础类型时,您才能将装箱值转换为枚举。如果你声明了

    enum Foo : byte { ...
    

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

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

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

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

    【讨论】:

    • 这绝对是规则......我想知道为什么会这样。
    • @DanM 不确定——这无疑与您不能直接从(例如)装箱字节到未装箱 int 的原因相同。我不确定语言设计者为什么会这样决定,但 Eric Lippert 已经写过几次,并且可能提到了一些原因。
    • 如果TValueFoo?,我得到“提供的类型必须是枚举”。但是,有一个简单的解决方法:var x = (TValue)Enum.ToObject(Nullable.GetUnderlyingType(typeof(TValue)), 1);。无论如何,这很有帮助。 +1。
    【解决方案2】:

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

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

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

    【讨论】:

    • 谢谢,但这绝对不能回答我的第二个问题,因为它需要是通用的(即,将 Nullable&lt;Foo&gt; 替换为 TValue)。
    • @DanM 泛型枚举的问题(嗯,一个问题)是你不知道底层类型是什么。只有当源值是相同类型时,直接转换才能成功。请改用 Enum 和/或 Convert 类的静态方法。
    猜你喜欢
    • 1970-01-01
    • 2011-02-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-24
    • 1970-01-01
    • 2011-08-18
    • 1970-01-01
    相关资源
    最近更新 更多