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