为什么enum
的集合无法转换为int?
enum Test { A = 1, B = 2 };
int? x = (int?)Test.A; // Valid
var collection1 = new[] { Test.A }.Cast<int>().ToList();
// InvalidCastException has thrown (Specified cast is not valid.)
var collection2 = new[] { Test.A }.Cast<int?>().ToList();
答案 0 :(得分:14)
Cast
方法只能在枚举类型及其基础整数类型之间执行装箱/拆箱转换,引用转换和转换。拆箱必须是正确的类型 - 它不能拆箱到可以为空的类型(与C#转换不同)。
var collection1 = new[] { Test.A }.Cast<int>()
.Select(x => (int?) x)
.ToList();
对于每个值,Cast
会从装箱的enum
值中取消装箱到int
值,然后Select
会转换int
值到int?
值。
在这种情况下,你也可以逃脱:
var collection1 = new[] { Test.A }.Select(x => (int?) x)
.ToList();
即。没有Cast
步骤。但是,如果你有一个object
数组,则不会工作:
// Fails
var collection1 = new object[] { Test.A }.Select(x => (int?) x)
.ToList();
您无法将装箱的枚举值取消装入可以为空的int值。 Cast
版本在这种情况下仍然适用,因为它会拆分两个步骤(首先取消装箱到int
,然后从int
转换为int?
。)
答案 1 :(得分:3)
这是因为内部Cast()
做了类似的事情:
object o = Test.A;
int i = (int)o; // This is valid.
int? ni = (int?)o; // This is not valid!
你必须先Cast()
到一个int:
var collection3 = new[] { Test.A }.Cast<int>().ToList().Cast<int?>().ToList();
或根本不使用Cast()
:
var collection4 = new object[] { Test.A, null }.Select(i => i == null ? null : (int?)(int)i).ToList();
答案 2 :(得分:0)
它不起作用,因为我们需要了解什么是枚举和什么是int? (可以为空)
int?实际上并不是一个int它是Nullable的通用实例, - 语法T?是System.Nullable的简写,其中T是值类型。这两种形式是可以互换的。 Link
枚举枚举元素的默认基础类型为int。Link
因此存在int和enum之间的隐式转换。但是,enum(int)与Nullable(完全不同的引用类型)之间的隐式转换不存在。这就是你看到InvalidCastException异常的原因。
在第一个int? x = (int?)Test.A;
语句中,您强制显式转换为包装值类型并获取整数或获取空值,这是有效的,因为将枚举装入object
然后取消装箱它为int?
返回一个int。
答案 3 :(得分:-1)
我不知道为什么Cast<>()
不起作用,但你可以使用Select()
做你想做的事。
var collection = new[] { Test.A }.Select(item => (int?)item).ToList();