Possible Duplicate:
Why is Func<T> ambiguous with Func<IEnumerable<T>>?Generics, độ phân giải quá tải và các đại biểu (xin lỗi, không thể tìm thấy một tiêu đề tốt hơn)
tôi nhận thấy một nghị quyết tình trạng quá tải vấn đề rất lạ với Generics ...
Xem xét các phương pháp sau:
static void Foo<TSource>(TSource element, Func<TSource, int> selector)
{
"int".Dump();
}
static void Foo<TSource>(TSource element, Func<TSource, double> selector)
{
"double".Dump();
}
static T Identity<T>(T value)
{
return value;
}
(C# 4, thử nghiệm trong LINQPad)
Nếu tôi cố gắng gọi Foo
với một biểu thức lambda như bộ chọn , Mọi thứ hoạt động tốt:
Foo(42, x => x); // prints "int"
Nhưng nếu tôi thay x => x
với Identity
, trình biên dịch không thể quyết định giữa 2 Foo
quá tải:
Foo(42, Identity);
// The call is ambiguous between the following methods or properties:
// 'UserQuery.Foo<int>(int, System.Func<int,int>)' and
// 'UserQuery.Foo<int>(int, System.Func<int,double>)'
Làm thế nào sự quá tải thứ hai có thể là một ứng cử viên hợp lệ? Loại suy luận xác định một cách chính xác rằng TSource
là int
, vì vậy tham số T
cho phương pháp Identity
phải là int
là tốt, vì vậy các kiểu trả về phải là int
quá ... Identity
có thể là một Func<int,int>
hoặc một Func<double,double>
, nhưng không phải là một Func<int,double>
!
Và nó trở nên tồi tệ hơn! Ngay cả khi tôi chỉ định tất cả các thông số loại một cách rõ ràng, tôi vẫn nhận được cùng một lỗi:
Foo<int>(42, Identity<int>); // The call is ambiguous...
Làm cách nào có thể có sự mơ hồ ở đây? Theo như tôi có thể nói, không có cách nào sự quá tải mất Func<int,double>
có thể là một ứng cử viên. Tôi đoán lời giải thích phải ở đâu đó trong các chi tiết kỹ thuật, nhưng tôi không thể tìm thấy bit có liên quan ... hoặc nó có thể là một lỗi trong trình biên dịch, nhưng tôi đoán nó không chắc.
Lưu ý rằng nó không làm việc nếu tôi dứt khoát tạo ra các đại biểu:
Foo(42, new Func<int, int>(Identity)); // prints "int"
Vì vậy, ai đó có thể giải thích những gì đang xảy ra ở đây? Ngoài ra, tại sao nó làm việc với một lambda nhưng không phải với một nhóm phương pháp?
Kiên nhẫn chờ Eric Lippert đăng * câu trả lời *. –
Điều gì xảy ra trong C# 3? Tôi nghi ngờ điều này có thể có một cái gì đó để làm với phương sai loại trong generics. –
@Anon, tôi đã không thử với C# 3, nhưng tôi không nghĩ rằng nó có bất cứ điều gì để làm với phương sai, bởi vì phương sai không áp dụng cho các loại giá trị –