
解开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中文网其他相关文章!