2010-04-06 8 views
8

Hãy có một ví dụ đơn giản sau:C# quá tải với generics: lỗi hoặc tính năng?

void Foo<T>(IEnumerable<T> collection, params T[] items) 
{ 
    // ... 
} 

void Foo<C, T>(C collection, T item) 
    where C : ICollection<T> 
{ 
    // ... 
} 

void Main() 
{ 
    Foo((IEnumerable<int>)new[] { 1 }, 2); 
} 

Compiler nói:

Loại 'System.Collections.Generic.IEnumerable' không thể được sử dụng như loại tham số 'C' trong các loại generic hay phương thức 'UserQuery.Foo (C, T)'. Không có chuyển đổi tham chiếu ngầm từ 'System.Collections.Generic.IEnumerable' thành 'System.Collections.Generic.ICollection'.

Nếu tôi thay đổi Main tới:

void Main() 
{ 
    Foo<int>((IEnumerable<int>)new[] { 1 }, 2); 
} 

Nó sẽ làm việc ok. Tại sao trình biên dịch không chọn phải quá tải?

+0

thực sự KHÔNG có chuyển đổi nào giữa IEnumerable và ICollection. – nothrow

+1

@Yossarian: hai điều. Đầu tiên, có một chuyển đổi rõ ràng. Bạn muốn nói "thực sự không có chuyển đổi tham chiếu ngầm định". Thứ hai, câu hỏi không phải là "tại sao tôi nhận được lỗi 'chuyển đổi không ngầm'?" Thứ hai, câu hỏi là "tại sao thuật toán phân giải quá tải chọn một ứng cử viên khớp chính xác không hợp lệ thay vì chọn ứng viên hợp lệ nhưng tệ hơn không khớp chính xác?" –

Trả lời

15

Câu hỏi của bạn được trả lời tại đây.

http://blogs.msdn.com/ericlippert/archive/2009/12/10/constraints-are-not-part-of-the-signature.aspx

hãy cũng đọc khoảng một triệu ý kiến ​​nói với tôi rằng tôi sai đối với một số lời bình luận thêm thú vị về vấn đề này.

+0

Ok. Cảm ơn bạn đã trả lời nhanh :) Tôi phải chờ một thời gian dài trước khi tôi có thể chấp nhận câu trả lời :) –

+0

Tôi biết rằng tôi đã đọc bài viết này và tôi đang tìm kiếm ... nhưng rõ ràng là bạn biết blog của mình tốt hơn tôi và tìm các bài viết nhanh hơn - đó là loại công bằng ... ^^ – tanascius

2

Tôi đoán là trình biên dịch chọn kết quả phù hợp nhất trước khi sử dụng ràng buộc chung. Trong ví dụ của bạn, phương thức có ràng buộc là thích hợp hơn vì nó không có tham số cuối cùng là params.

Chỉnh sửa - Eric Lippert xác nhận điều này trong câu trả lời của mình.

+0

Có. Cảm ơn:) –