.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
に変換すると失敗します。これは、最初のコード スニペットとそれに対応する LINQ が期待どおりに動作しない理由を説明しています。 long
解決策を探しています
この例外を回避するには、変換を明示的に実行する必要があります:
<code class="language-csharp">var castedList = list.Select(i => (long)i);</code>
この異常な動作は、いくつかの微妙な舞台裏のメカニズムがコードの実行に影響を与える可能性があることを思い出させます。将来同様の落とし穴が起こらないようにするために、代替手段を検討するか、変換を明示的に処理する価値があります。
以上が.NET 3.5 SP1 で「Enumerable.Cast」が「InvalidCastException」をスローするのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。