[英]Why is a collection of <enum> unable to cast to an <int?>?
为什么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();
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?
。
这是因为内部的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();
它不起作用,因为我们需要了解什么是枚举和什么是int? (可以为空)
诠释? 是不是真的是一个int它是Nullable的通用实例, - 语法T? 是System.Nullable的简写,其中T是值类型。 这两种形式是可以互换的。 链接
枚举枚举元素的默认基础类型是int。 链接
因此,存在int和enum之间的隐式转换。 但是,enum(int)与Nullable(完全不同的引用类型)之间的隐式转换不存在。 这就是您看到InvalidCastException异常的原因。
在第一个int? x = (int?)Test.A;
int? x = (int?)Test.A;
声明你强制显式转换为框的值类型并获得一个整数或获得一个null,这是有效的,因为将枚举装入object
然后将其拆箱为int?
正在返回一个int。
我不知道为什么Cast<>()
不起作用,但你可以使用Select()
来做你想要的。
var collection = new[] { Test.A }.Select(item => (int?)item).ToList();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.