2009-12-08 4 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에 대한 Cast 확장 기능을 사용하는 것이지만 InvalidCastException을 제공하고 이유를 이해하지 못합니다. 내 해결 방법은 Select를 대신 사용하는 것이지만 Cast는 더 멋지게 보입니다.

누군가가 Cast 메소드가 작동하지 않는 이유를 말해 줄 수 있습니까?

는 희망 아래 코드는 내 문제를 보여

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 ... 묻기 전에 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

관련 문제