解開Enumerable.Cast()
拋出InvalidCastException
的謎團
在.NET 3.5 SP1中,使用Cast<T>()
轉換IEnumerable
時,令人費解地拋出了InvalidCastException
異常。考慮以下程式碼:
<code class="language-csharp">IEnumerable<int> list = new List<int>() { 1 }; IEnumerable<long> castedList = list.Cast<long>(); Console.WriteLine(castedList.First());</code>
為什麼這段程式碼會拋出異常?
這種異常行為源自於.NET 3.5和.NET 3.5 SP1之間Cast<T>()
方法行為的改變。在SP1之前,Cast<T>()
作用於IEnumerable<T>
,允許直接轉換。然而,在SP1中,它被修改為作用於IEnumerable
,這意味著元素在轉換之前會被拆箱為System.Object
。
這種拆箱操作會導致InvalidCastException
,因為與直接將int
轉換為long
不同,不允許將已裝箱的int
轉換為long
。實際上,這段程式碼嘗試以下操作:
<code class="language-csharp">int i = 1; object o = i; long l = (long)o;</code>
這也會導致相同的InvalidCastException
。
解法與解釋
為了解決這個問題,可以使用lambda表達式來明確轉換元素:
<code class="language-csharp">var castedList = list.Select(i => (long)i);</code>
這將成功地將元素轉換為long
。
這種行為的原因在於Cast<T>()
是IEnumerable
的擴展方法,而不是IEnumerable<T>
的擴展方法。當元素到達轉換階段時,它們已經被裝箱為object
。當從object
轉換為特定類型時,這會導致InvalidCastException
。
以上是為什麼「IEnumerable.Cast()」在 .NET 3.5 SP1 中拋出「InvalidCastException」?的詳細內容。更多資訊請關注PHP中文網其他相關文章!