2010-06-14 44 views
6

Các mã sau đây không biên dịch (error CS0123: No overload for 'System.Convert.ToString(object)' matches delegate 'System.Converter<T,string>'):Độ phân giải quá tải nhóm phương pháp khác với độ phân giải quá tải cuộc gọi phương thức?

class A<T> { 
    void Method(T obj) { 
     Converter<T, string> toString = Convert.ToString; 

     // this doesn't work either (on .NET 4): 
     Converter<object, string> toString2 = Convert.ToString; 
     Converter<T, string> toString3 = toString2;    
    } 
} 

Tuy nhiên, điều này không:

class A<T> { 
    void Method(T obj) { 
     // o is a T, and Convert.ToString(o) is using 
     // string Convert.ToString(object o) 

     Converter<T, string> toString = o => Convert.ToString(o); 
    } 
} 

Trong C# 4, các đại biểu đồng/trường hợp bị biến thể có thể được gán cho mỗi khác, và đại biểu có thể được tạo từ phương pháp co/contra-variant, do đó, phương pháp ToString(object) có thể được sử dụng làm Converter<T, string>, vì T luôn luôn có khả năng chuyển đổi thành số object.

Vì vậy, ví dụ đầu tiên (phương pháp phân giải quá tải nhóm phương pháp) nên tìm phương pháp áp dụng duy nhất string Convert.ToString(object o), giống như phương pháp gọi quá tải độ phân giải. Tại sao nhóm phương pháp & giải quyết quá tải cuộc gọi phương thức tạo ra các kết quả khác nhau?

Trả lời

3

Điều này phải làm với thực tế là phương sai không áp dụng cho các loại giá trị, vì vậy nếu bạn giới hạn T như where T : class, bạn có được phương sai trên T và đoạn mã đầu tiên sẽ biên dịch.

Từ Covariance and Contravariance FAQ:

Variance chỉ được hỗ trợ nếu một tham số kiểu là một loại tài liệu tham khảo. Phương sai không được hỗ trợ cho các giá trị loại.

+0

Cụ thể hơn, nó không hoạt động đối với 'T' không bị ràng buộc bởi vì nó _might be_ một loại giá trị. – thecoop

0

Mã thứ hai biên dịch vì oxuất phát từobject, vì vậy rõ ràng là bạn có thể gọi một phương pháp mà phải mất một object như đầu vào với bất kỳ loại tham số.

Các loại đại biểu, tuy nhiên, là không bằng. Trừ khi Tobject chữ ký của phương thức không khớp. Nếu, giả sử, Tint bạn sẽ có một Converter<int, string> không giống như Converter<object, string. Chúng là hai loại hoàn toàn loại khác nhau.

Bạn đang gặp phải các vấn đề xung quanh việc thiếu co/contra-variance của C# 3.0. Nên tốt hơn trong C# 4.

+0

Đây là trong .NET 4. Tôi đã cập nhật câu hỏi của mình – thecoop

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