以下の内容はhttps://oita.oika.me/2013/11/03/linq_cast/より取得しました。


C# IEnumerable.Castメソッドでint→longはできない

表題のとおり。
LINQのCastでint→longとかint→shortとか、
その他数値間のキャストをしようとすると
InvalidCastExceptionで落ちる。最近知った。
OfType()だとエラーにはならないが、要素が1つも返ってこない。

コードは以下。

int[] ints = new [] { 1, 2, 3 };  
long[] longs = ints.Cast<long>().ToArray(); //throws InvalidCastException  

ToArray()はクエリを実行させるために入れてるだけなので何でも良い。

んで、理由はCastメソッドの実体を覗くとよくわかる。
(ILSpyで見たもの)

// System.Linq.Enumerable  
private static IEnumerable<TResult> CastIterator<TResult>(IEnumerable source)  
{  
 foreach (object current in source)  
 {  
  yield return (TResult)((object)current);  
 }  
 yield break;  
}  

このCastメソッドはジェネリックでないIEnumerableの拡張メソッドなので
いったんobject型にキャストしてから目的の型にキャストしてるわけだ。
このobjectへのキャストのときにボックス化が起きてしまって、
ボックス化解除のときに型が一致しないので失敗する。
詳しくはMSDNの説明参照 →ボックス化解除変換

そんなわけで、Castの代わりにSelectメソッドとか使いましょう。

int[] ints = new [] { 1, 2, 3 };  
long[] longs = ints.Select(i => (long)i).ToArray();  

 
以上。




以上の内容はhttps://oita.oika.me/2013/11/03/linq_cast/より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14