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?
thực sự KHÔNG có chuyển đổi nào giữa IEnumerable và ICollection. – nothrow
@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?" –