2009-12-08 23 views
6

重複の可能性:
Enumerable.Cast<T> extension method fails to cast from int to long, why ?
Puzzling Enumerable.Cast InvalidCastException
Cast/Convert IEnumerable<T> to IEnumerable<U> ?()がIEnumerable <int>で動作しないのはなぜですか?

私はdoubleの配列に整数の配列を変換しようとしている(私は取る関数に渡すことができます二重の配列)。

最も明白な解決策(少なくとも私にとっては)は、IEnumerableのキャスト拡張機能を使用することですが、それは私にInvalidCastExceptionを与えます。理由はわかりません。私の回避策はSelectを代わりに使用することですが、キャストはきれいに見えます。

キャスト方式が機能しない理由を教えてもらえますか?

うまくいけば、以下のコードは、私の問題を示す:

namespace ConsoleApplication1 
{ 
    using System; 
    using System.Collections.Generic; 
    using System.Linq; 

    class Program 
    { 
     static void Main() 
     { 
      var intArray = new[] { 1, 2, 3, 4 }; 
      PrintEnumerable(intArray, "intArray: "); 

      var doubleArrayWorks = intArray.Select(x => (double)x).ToArray(); 
      PrintEnumerable(doubleArrayWorks, "doubleArrayWorks: "); 

      // Why does this fail?? 
      var doubleArrayDoesntWork = intArray.Cast<double>().ToArray(); 
      PrintEnumerable(doubleArrayDoesntWork, "doubleArrayDoesntWork: "); 

      // Pause 
      Console.ReadLine(); 
     } 

     private static void PrintEnumerable<T>(
      IEnumerable<T> toBePrinted, string msgPrefix) 
     { 
      Console.WriteLine(
       msgPrefix + string.Join(
        ",", toBePrinted.Select(x => x.ToString()).ToArray())); 
     } 
    } 

}

+0

私は質問する前に十分に慎重にStack Overflowをチェックしませんでした。私は私の質問が既に尋ねられ、答えられていることが分かった:http://stackoverflow.com/questions/1684448/enumerable-castt-extension-method-fails-to-cast-from-int-to-long-why – dominic

答えて

2

ArrayクラスのConvertallの方法を使用してみてください。それは、あなたが変換を明示的に制御できるようにします。

var doubleArray = Array.ConvertAll<int, double>(intArray, num => (double)num); 

これは、発生している内部エラーを回避します。

他の方法でも、変換プロセスを明示的に制御できます。

+1

それは同じ選択を使用しています。 – Dykam

9

問題は、コンパイル時にキャスト演算子(オーバーロード)が解決されるという問題が原因です。 キャストがどのように実装されているか考えてみてください。

public static IEnumerable<T> Cast<T>(this IEnumerable source) 
{ 
    foreach(object element in source) 
    { 
     yield return (T)(object)element; 
    } 
} 

コンパイラが持っているすべての情報は、それが型Tにそしてそれは、デフォルトの継承キャストを使用することのためにオブジェクトをキャストする必要があるということである:私は、コードは次のようになります賭けます。カスタムオーバーロードされた演算子は使用されません。あなたの例では、intはdoubleではないので、キャストは失敗します。

選択例:

source.Select(a => (double)a)); 

作品コンパイラは両方のタイプを知っているし、それが適切なオーバーロードされたオペレーターを呼び出すことができますので。

+0

ここで注目すべき主なことは、おそらく、型キャスト_syntax_は、型キャスト変換演算子と型変換演算子の両方に使用されていることでしょう。数値型間の変換は変換演算子であり、キャストはありません。 – Joey

関連する問題