.NET 3.5 SP1 中 Enumerable.Cast
抛出 InvalidCastException
在 .NET 3.5 SP1 中,使用 Enumerable.Cast
方法将一种类型的集合转换为另一种类型时,观察到一种特殊行为。以下代码:
<code class="language-csharp">IEnumerable<int> list = new List<int>() { 1 }; IEnumerable<long> castedList = list.Cast<long>(); Console.WriteLine(castedList.First());</code>
意外地抛出 InvalidCastException
。当使用 LINQ 语法时,也会出现这个令人费解的错误,如下面的代码所示:
<code class="language-csharp">var list = new[] { 1 }; var castedList = from long l in list select l; Console.WriteLine(castedList.First());</code>
揭示隐藏的行为
起初,这种转换为什么会失败似乎令人困惑。但是,一篇博文阐明了潜在的问题。在 .NET 3.5 SP1 中,Cast<T>()
方法被修改为作用于 IEnumerable
而不是 IEnumerable<T>
。因此,集合中的每个元素在到达转换阶段之前都被装箱到 System.Object
中。
暴露根本原因
这种根本性的转变导致了一个细微的问题。InvalidCastException
本质上是由尝试以下转换引起的:
<code class="language-csharp">int i = 1; object o = i; long l = (long)o;</code>
如这段代码所示,将 int
直接转换为 long
会产生预期结果;但是,将装箱的 int
转换为 long
会失败。这就解释了为什么初始代码片段及其 LINQ 对应部分无法按预期工作。
寻找解决方法
为了避免这种异常,必须显式地执行转换:
<code class="language-csharp">var castedList = list.Select(i => (long)i);</code>
这种替代方法成功地转换了每个元素,而不会遇到无效的转换异常。
这种不寻常的行为提醒我们,一些细微的幕后机制可能会影响代码执行。为了避免将来出现类似的陷阱,值得探索替代方法或显式处理转换。
以上是为什么'Enumerable.Cast”在 .NET 3.5 SP1 中抛出'InvalidCastException”?的详细内容。更多信息请关注PHP中文网其他相关文章!