[英]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.