表題のとおり。
LINQのCast
その他数値間のキャストをしようとすると
InvalidCastExceptionで落ちる。最近知った。
OfType
コードは以下。
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();
以上。