2009-12-08 38 views
6

Bản sao có thể xảy ra:
Enumerable.Cast<T> extension method fails to cast from int to long, why ?
Puzzling Enumerable.Cast InvalidCastException
Cast/Convert IEnumerable<T> to IEnumerable<U> ?Tại sao không Cast <double>() hoạt động trên IEnumerable <int>?

Tôi đang cố gắng để chuyển đổi một mảng các số nguyên để một loạt các đôi (vì vậy tôi có thể vượt qua nó để một hàm mang theo một mảng đôi).

Giải pháp rõ ràng nhất (với tôi, ít nhất) là sử dụng chức năng mở rộng Cast cho IEnumerable, nhưng nó mang lại cho tôi một InvalidCastException và tôi không hiểu tại sao. Giải pháp thay thế của tôi là sử dụng Chọn thay thế, nhưng tôi nghĩ Cast trông có vẻ nấp.

Ai đó có thể cho tôi biết tại sao phương thức Truyền không hoạt động?

Hy vọng rằng các mã dưới đây minh họa vấn đề của tôi:

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

Rất tiếc ... Tôi không kiểm tra tràn ngăn xếp cẩn thận trước khi yêu cầu. Tôi đã tìm thấy câu hỏi của mình đã được yêu cầu và trả lời: http://stackoverflow.com/questions/1684448/enumerable-castt-extension-method-fails-to-cast-from-int-to-long-why – dominic

Trả lời

2

Hãy thử sử dụng các phương pháp ConvertAll của lớp Array. Nó cho phép bạn kiểm soát rõ ràng việc chuyển đổi.

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

Điều này bỏ qua lỗi nội bộ mà bạn đang gặp phải.

Các phương pháp khác cho phép bạn kiểm soát rõ ràng quy trình chuyển đổi.

+1

Điều tương tự như sử dụng lựa chọn. – Dykam

9

Sự cố xuất phát từ thực tế là các toán tử truyền (quá tải) được giải quyết tại thời gian biên dịch. Hãy thử nghĩ cách triển khai Truyền. Tôi đặt cược mã trông giống như sau:

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

Tất cả thông tin trình biên dịch cần phải đưa đối tượng vào loại T. Và vì nó sẽ sử dụng phép truyền thừa kế mặc định. Không có toán tử quá tải tùy chỉnh nào được sử dụng. Và trong ví dụ của bạn một int không phải là một đôi để cast sẽ thất bại.

Các chọn ví dụ:

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

công trình vì trình biên dịch biết cả hai loại và nó có thể gọi tổng đài quá tải thích hợp.

+0

Điều quan trọng cần quan sát ở đây có lẽ là typecast _syntax_ được sử dụng cho cả toán tử chuyển đổi _and_. Chuyển đổi giữa các loại số là toán tử chuyển đổi, không phải là phôi. – Joey

Các vấn đề liên quan