2010-01-04 39 views
8

Nếu một phương pháp có tham số kiểu System.Collections.IList tôi có thể hợp pháp/an toàn chuyển giá trị kiểu System.Collections.Generic.IEnumerable<T> không?Chuyển đổi IEnumerable <T> sang IList

tôi sẽ đánh giá cao một lời giải thích thấu đáo về lý do tại sao điều này có thể và những gì thực sự xảy ra với đối tượng T khi IEnumerable<T> được sử dụng bên trong của phương pháp.

Nó có được chuyển đổi thành loại đối tượng cơ sở không?

Được sử dụng làm System.Collections.IEnumerable?

Có bất kỳ trường hợp nào điều này sẽ gây ra sự cố (tức là sự cố về hiệu suất) không?

Cảm ơn trước, John

Trả lời

25

Không, Bạn không thể vượt qua một IEnumerable<T> đến một phương pháp mà mất IList. Giao diện IEnumerable<T> không thể chuyển đổi thành IList và cố chuyển biến loại IEnumerable<T> sang phương thức lấy IList sẽ dẫn đến lỗi biên dịch.

Để thực hiện việc này, bạn sẽ cần phải làm một trong những cách sau

  1. Thay vì có một IEnumerable<T>, duy trì một tham chiếu đến một loại mà thực hiện cả hai IEnumerable<T>IList. List<T> là một ứng cử viên tốt ở đây
  2. Chuyển đổi ví dụ IEnumerable<T> thành một đối tượng mới có thể chuyển đổi thành IList. Ví dụ: trong 3.5+ bạn có thể gọi phương thức mở rộng .ToList() để tạo List<T> mới trong quá trình liệt kê.
2

số Bạn không có thể, mà không sử dụng phương pháp ToList() mở rộng. Tôi nghĩ rằng điều này không nên gây ra rằng vấn đề lớn về hiệu suất - nếu bạn có sự thay thế, hãy so sánh thời gian và so sánh.

Bạn cũng có thể sử dụng new List<T>(myIEnumerable) - tài liệu nói rằng chức năng đó là hoạt động O(n), nhưng tôi không thể tìm thấy bất kỳ điều gì khác về ToList(). Ngoài ra, hãy nhớ rằng List<T> cũng thực hiện IList cũng như IList<T>.

1

IEnumerable không cho phép lập chỉ mục quyền truy cập vào bộ sưu tập, trong khi IList thực hiện. Vì vậy, IList là nhiều hơn IEnumerable và bạn sẽ không thể để có được đi với nó. Tất nhiên, một số lớp thực hiện cả hai giao diện (ví dụ: Danh sách <>) và những lớp đó sẽ hoạt động tốt.

Nếu bạn cần chuyển từ IEnumerable sang IList, bạn có thể thử dàn diễn viên đầu tiên, nếu bạn may mắn, nó sẽ hoạt động. Nếu không, bạn sẽ phải bỏ qua bộ sưu tập IEnumerable và xây dựng một IList mới.

Chỉnh sửa: sử dụng ToList() thay vì tự nghiên cứu như những người khác đã đề xuất.

0

Không, bạn không thể chuyển nó qua IEnumerable. IList thực hiện IEnumerable, vì vậy nếu bạn chuyển phương thức của bạn thành một IList, bạn có thể sử dụng nó một cách an toàn như một IEnumerable. VS sẽ không biên dịch như sau:

private static void Test(IList<int> list){ } 

Test(Enumerable.Range(0, 10)); 

Lỗi trả về:

Argument '1': cannot convert from System.Collections.Generic.IEnumerable<int>' to 'System.Collections.Generic.IList<int>' 
Các vấn đề liên quan