2009-12-08 6 views
6

mögliche Dubletten:
Enumerable.Cast<T> extension method fails to cast from int to long, why ?
Puzzling Enumerable.Cast InvalidCastException
Cast/Convert IEnumerable<T> to IEnumerable<U> ?Warum wird Cast <double>() auf IEnumerable <int> nicht funktionieren?

Ich versuche, ein Array von ganzen Zahlen in ein Array von Doppel zu konvertieren (so kann ich es an eine Funktion, die nimmt eine Reihe von Doppel).

Die offensichtlichste Lösung (zumindest für mich) ist die Verwendung der Cast-Erweiterungsfunktion für IEnumerable, aber es gibt mir eine InvalidCastException, und ich verstehe nicht warum. Meine Problemumgehung besteht darin, Select zu verwenden, aber ich denke, Cast sieht ordentlicher aus.

Kann mir jemand sagen, warum die Cast-Methode nicht funktioniert?

Hoffentlich wird der Code unten zeigt mein Problem:

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

Hoppla ... Ich habe Stack Overflow nicht sorgfältig genug geprüft, bevor ich gefragt habe. Ich habe festgestellt, dass meine Frage bereits gestellt und beantwortet wurde: http://stackoverflow.com/questions/1684448/enumerable-castt-extension-method-fails-to-cast-from-int-to-long-why – dominic

Antwort

2

Versuchen Sie, die ConvertAll Methode der Array-Klasse verwenden. Es gibt Ihnen explizite Kontrolle über die Konvertierung.

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

Dies umgeht den internen Fehler, der aufgetreten ist.

Andere Methoden geben Ihnen auch explizite Kontrolle über den Konvertierungsprozess.

+1

Das ist das Gleiche wie mit auswählen. – Dykam

9

Das Problem kommt von der Tatsache, dass Cast-Operatoren (überladen) zur Kompilierzeit aufgelöst werden. Versuchen Sie zu überlegen, wie Cast implementiert ist. Ich wette, der Code wie folgt aussieht:

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

Alle Infos der Compiler hat ist, dass es um ein Objekt zu einem Typ T. zu werfen braucht Und dass es die Standardvererbungs Gießen verwenden. Es wird kein benutzerdefinierter überladener Operator verwendet. Und in Ihrem Beispiel ist ein Int kein Double, also wird der Cast fehlschlagen.

Das Auswahl Beispiel:

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

funktioniert, weil die Compiler beiden Typen kennen und es ist in der Lage, den entsprechenden überladenen Operator zu nennen.

+0

Die wichtigste Sache, die hier zu beachten ist, ist wahrscheinlich, dass die Typumwandlung _syntax_ sowohl für Typcasts als auch für Konvertierungsoperatoren verwendet wird. Konvertierungen zwischen numerischen Typen sind Konvertierungsoperatoren, keine Umwandlungen. – Joey

Verwandte Themen