2016-01-29 23 views
12

Hoàn câu hỏi trước mã:Tại sao là IEnumerable (T) không được chấp nhận như phương pháp mở rộng nhận

Tại sao IEnumerable<T>where T : ITest không được chấp nhận như thu của một phương pháp mở rộng mà hy vọng this IEnumerable<ITest>?

Và bây giờ là đang:

Tôi có ba loại:

public interface ITest { } 
public class Element : ITest { } 
public class ElementInfo : ITest { } 

Và hai phần mở rộng phương pháp:

public static class Extensions 
{ 
    public static IEnumerable<ElementInfo> Method<T>(
     this IEnumerable<T> collection) 
     where T : ITest 
    { 
→  return collection.ToInfoObjects(); 
    } 

    public static IEnumerable<ElementInfo> ToInfoObjects(
     this IEnumerable<ITest> collection) 
    { 
     return collection.Select(item => new ElementInfo()); 
    } 
} 

Các lỗi biên dịch tôi nhận được (trên dòng rõ rệt) :

CS1929: 'IEnumerable<T>' không chứa một định nghĩa cho 'ToInfoObjects' và phần mở rộng tốt nhất phương pháp quá tải 'Extensions.ToInfoObjects(IEnumerable<ITest>)' đòi hỏi một máy thu kiểu 'IEnumerable<ITest>'

Tại sao điều này như vậy? Người nhận phương thức mở rộng ToInfoObjectsIEnumerable<T> và theo loại ràng buộc chung, T phải triển khai ITest.

Tại sao người nhận không được chấp nhận? Đoán của tôi là hiệp phương sai của IEnumerable<T> nhưng tôi không chắc chắn.

Nếu tôi thay đổi ToInfoObjects để nhận IEnumerable<T> where T : ITest, thì mọi thứ đều ổn.

Trả lời

13

Hãy xem xét điều này:

public struct ValueElement : ITest { } 

và điều này:

IEnumerable<ValueElement> collection = ... 
collection.Method(); //OK, ValueElement implement ITest, as required. 
collection.ToInfoObjects() //Error, IEnumerable<ValueElement> is not IEnumerable<ITest> 
          //variance does not work with value types. 

Vì vậy, đó không phải là tất cả các loại cho phép Method cũng cho phép ToInfoObjects. Nếu bạn thêm class ràng buộc vào T trong Method, thì mã của bạn sẽ biên dịch.

+0

Câu trả lời thực sự hay. Sự tôn trọng. – Vasilievski

+0

Bây giờ bạn đã nói điều đó, nó có vẻ hiển nhiên đối với tôi. T có thể là loại giá trị và tất nhiên nó sẽ không hoạt động. Cảm ơn nhiều. Theo dõi, tôi muốn [liên kết đến lý do] (http://stackoverflow.com/questions/12454794/why-covariance-and-contravariance-do-not-support-value-type) tại sao đồng (ntra) phương sai không hoạt động với các loại giá trị. –

-1

Bạn có thể làm như sau:

public static IEnumerable<ElementInfo> Method<T>(
     this IEnumerable<T> collection) 
     where T : ITest 
    { 
     return collection.ToInfoObjects(); 
    } 

    public static IEnumerable<ElementInfo> ToInfoObjects<T>(
     this IEnumerable<T> collection) 
    { 
     return collection.Select(item => new ElementInfo()); 
    } 

Thông báo về việc ToInfoObjects.

+0

Cảm ơn đề xuất của bạn, nhưng tôi biết những gì tôi có thể làm để giải quyết vấn đề và thậm chí nhiều hơn, tôi đã viết nó trong bài đăng gốc. Điều tôi muốn là biết tại sao vấn đề xảy ra, không phải là cách giải quyết nó. –

+0

@KornelijePetak Oh, xin lỗi vì đã không chú ý đủ đến câu hỏi của bạn. –

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