[英]Why is a collection of <enum> unable to cast to an <int?>?
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();
The Cast
method can only perform boxing/unboxing conversions, reference conversions, and conversions between an enum type and its underlying integral type. Cast
方法只能在枚举类型及其基础整数类型之间执行装箱/拆箱转换,引用转换和转换。 The unboxing has to be to the right type though - it can't unbox to a nullable type (unlike the C# conversion). 取消装箱必须是正确的类型 - 它不能取消装入可以为空的类型(与C#转换不同)。
var collection1 = new[] { Test.A }.Cast<int>()
.Select(x => (int?) x)
.ToList();
For each value, the Cast
will unbox from the boxed enum
value to the int
value, and then the Select
will convert the int
value to an int?
对于每个值,
Cast
会从盒装enum
值中取消框到int
值,然后Select
会将int
值转换为int?
value. 值。
In this case you can also get away with this: 在这种情况下,你也可以逃避:
var collection1 = new[] { Test.A }.Select(x => (int?) x)
.ToList();
ie no Cast
step. 即没有
Cast
步骤。 However, that doesn't work if you have an object
array instead: 但是,如果您有一个
object
数组, 则不起作用:
// Fails
var collection1 = new object[] { Test.A }.Select(x => (int?) x)
.ToList();
You can't unbox a boxed enum value to a nullable int value. 您不能将装箱的枚举值取消装入可以为空的int值。 The
Cast
version still works in that case, however, as it splits the two steps (unboxing first to int
, then converting from int
to int?
.) 然而,在这种情况下,
Cast
版本仍然适用,因为它拆分了两个步骤(首先拆箱为int
,然后从int
转换为int?
。
It is because internally Cast()
does something like: 这是因为内部的
Cast()
做了类似的事情:
object o = Test.A;
int i = (int)o; // This is valid.
int? ni = (int?)o; // This is not valid!
You would have to first Cast()
to an int: 你必须首先将
Cast()
转换为int:
var collection3 = new[] { Test.A }.Cast<int>().ToList().Cast<int?>().ToList();
or not use Cast()
at all: 或者根本不使用
Cast()
:
var collection4 = new object[] { Test.A, null }.Select(i => i == null ? null : (int?)(int)i).ToList();
It wouldn't work because we need to understand what is enum and what is int? 它不起作用,因为我们需要了解什么是枚举和什么是int? (nullable int)
(可以为空)
int? 诠释? is not really an int it is a generic instance of Nullable, - The syntax T?
是不是真的是一个int它是Nullable的通用实例, - 语法T? is shorthand for System.Nullable, where T is a value type.
是System.Nullable的简写,其中T是值类型。 The two forms are interchangeable.
这两种形式是可以互换的。 Link
链接
Enum The default underlying type of the enumeration elements is int. 枚举枚举元素的默认基础类型是int。 Link
链接
Therefore an implicit conversion between int and enum exists. 因此,存在int和enum之间的隐式转换。 But implicit conversion between an enum(int) to Nullable (which is entirely different reference type) doesnt exist.
但是,enum(int)与Nullable(完全不同的引用类型)之间的隐式转换不存在。 That is why you see an InvalidCastException exception.
这就是您看到InvalidCastException异常的原因。
Where as in the first int? x = (int?)Test.A;
在第一个
int? x = (int?)Test.A;
int? x = (int?)Test.A;
statement you are forcing the explicit conversion to either box the value type and get an integer or get a null, which is works because boxing an enum into object
then unboxing it as int?
声明你强制显式转换为框的值类型并获得一个整数或获得一个null,这是有效的,因为将枚举装入
object
然后将其拆箱为int?
is returning an int. 正在返回一个int。
我不知道为什么Cast<>()
不起作用,但你可以使用Select()
来做你想要的。
var collection = new[] { Test.A }.Select(item => (int?)item).ToList();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.