2009-12-08 7 views
6

duplicados posibles:
Enumerable.Cast<T> extension method fails to cast from int to long, why ?
Puzzling Enumerable.Cast InvalidCastException
Cast/Convert IEnumerable<T> to IEnumerable<U> ?¿Por qué no Cast <double>() funciona en IEnumerable <int>?

Estoy tratando de convertir una matriz de enteros a una serie de dobles (por lo que puede pasar a una función que toma un conjunto de dobles).

La solución más obvia (para mí, al menos) es utilizar la función de extensión de Cast para IEnumerable, pero me da una InvalidCastException, y no entiendo por qué. Mi solución es utilizar Select en su lugar, pero creo que Cast se ve más ordenado.

¿Podría alguien decirme por qué el método Cast no funciona?

Esperemos que el código de abajo ilustra mi problema:

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

Ooops ... No revisé el desbordamiento de pila con suficiente cuidado antes de preguntar. Encontré que mi pregunta ya fue hecha y respondida: http://stackoverflow.com/questions/1684448/enumerable-castt-extension-method-fails-to-cast-from-int-to-long-why – dominic

Respuesta

2

Trate de usar el método ConvertAll de la clase Array. Le da control explícito sobre la conversión.

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

Esto omite el error interno que está experimentando.

Otros métodos también le dan un control explícito sobre el proceso de conversión.

+1

Eso es lo mismo como usar seleccionar. – Dykam

9

El problema proviene del hecho de que los operadores de conversión (sobrecargados) se resuelven en tiempo de compilación. Intenta pensar cómo se implementa Cast. Apuesto a que el código es el siguiente:

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

Toda la información que el compilador tiene es que se necesita lanzar un objeto a un tipo T. Y para ello se utilizará la fundición de herencia predeterminado. No se usará ningún operador personalizado sobrecargado. Y en tu ejemplo, un int no es un doble, por lo que el elenco fallará.

El selecto ejemplo:

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

obras porque el compilador sabe ambos tipos y es capaz de llamar al operador sobrecargado apropiado.

+0

Lo principal a observar aquí es que probablemente el tipo _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _. Las conversiones entre tipos numéricos son operadores de conversión, no conversiones. – Joey

Cuestiones relacionadas