Unravel the mystery of Enumerable.Cast()
thrownInvalidCastException
In .NET 3.5 SP1, a Cast<T>()
exception was puzzlingly thrown when converting IEnumerable
using InvalidCastException
. Consider the following code:
<code class="language-csharp">IEnumerable<int> list = new List<int>() { 1 }; IEnumerable<long> castedList = list.Cast<long>(); Console.WriteLine(castedList.First());</code>
Why does this code throw an exception?
This unusual behavior stems from changes in the behavior of the Cast<T>()
method between .NET 3.5 and .NET 3.5 SP1. Prior to SP1, Cast<T>()
acted on IEnumerable<T>
, allowing direct conversion. However, in SP1, it was modified to work on IEnumerable
, which means the element is unboxed to System.Object
before being converted.
This unboxing operation results in InvalidCastException
because unlike converting int
directly to long
, converting a boxed int
to long
is not allowed. Effectively, this code attempts to do the following:
<code class="language-csharp">int i = 1; object o = i; long l = (long)o;</code>
This will also result in the same InvalidCastException
.
Solutions and explanations
To solve this problem, you can use lambda expressions to explicitly convert the elements:
<code class="language-csharp">var castedList = list.Select(i => (long)i);</code>
This will successfully convert the element to long
.
is that Cast<T>()
is an extension method of IEnumerable
, not of IEnumerable<T>
. When elements reach the transformation stage, they have already been boxed as object
. This results in object
when converting from InvalidCastException
to a specific type.
The above is the detailed content of Why Does `IEnumerable.Cast()` Throw an `InvalidCastException` in .NET 3.5 SP1?. For more information, please follow other related articles on the PHP Chinese website!