tôi đã tiến hành các cuộc thử nghiệm suy luận sau:Tại sao C# không thể suy ra loại đối số loại chung tạo thành chữ ký của phương thức tĩnh không chung chung?
static class InferenceTest {
static void TakeInt(int a) { }
static int GiveInt() { return 0; }
static int TakeAndGiveInt(int a) { return 0; }
static void ConsumeAction1<T>(Action<T> a) { }
static void ConsumeFunc1<T>(Func<T> f) { }
static void ConsumeFunc2a<T1, T2>(Func<T1, T2> f) { }
static void ConsumeFunc2b<T>(Func<int, T> f) { }
static void ConsumeFunc2c<T>(Func<T, T> f) { }
static void ConsumeFunc1Func2<T1, T2>(Func<T1> f1, Func<T1, T2> f2) { }
static void Main() {
ConsumeAction1(TakeInt); //error
ConsumeFunc1(GiveInt); //ok
ConsumeFunc2a(TakeAndGiveInt); //error
ConsumeFunc2b(TakeAndGiveInt); //ok
ConsumeFunc2c(TakeAndGiveInt); //error
ConsumeFunc1Func2(GiveInt, TakeAndGiveInt); //ok
}
}
Kết quả dường như cho thấy rằng biên dịch C# là không thể suy ra những lập luận kiểu chung cho các thông số chức năng đại biểu từ một nhóm phương pháp không chung chung.
gì tôi puzzles nhất là C# là có thể suy ra những lập luận kiểu cho Func<T1, T2>
từ các giá trị trở lại phương pháp trong ConsumeFunc1Func2
, nhưng không thể suy ra các loại cho Func<T, T>
trong ConsumeFunc2c
.
Câu hỏi này tương tự như câu hỏi T of Func<S, T> is inferred from output of lambda expression only when S and T are different?, nhưng thay vì lambdas với các loại tham số không xác định, chúng tôi có nhóm phương pháp không chung chung.
Why can't C# infer type from this seemingly simple, obvious case câu hỏi trả lời các câu hỏi "Tại sao các phương pháp không chung chung không mơ hồ không đủ để suy luận?" và "Tại sao có sự khác biệt giữa các loại đối số và kiểu giá trị trả về cho suy luận?".
Câu hỏi:
Tại sao # biên dịch C có thể suy ra các loại Func<T>
sử dụng các loại giá trị trả về, nhưng không nhìn thấy sự thành công trong trường hợp Func<T, T>
?
Tại sao # biên dịch C có thể suy ra các lập luận T1
kiểu cho Func<T1, T2>
từ Func<T1>
trong ConsumeFunc1Func2
, nhưng không thể suy ra các lập luận T
kiểu cho Func<T, T>
từ chính nó trong ConsumeFunc2c
mà có vẻ là dễ dàng hơn?
Trong ConsumeFunc1Func2, biên dịch vẫn chỉ suy ra từ giá trị trả về, không phải kiểu tham số. T1 được giải quyết từ giá trị trả về của GiveInt, và T2 được giải quyết từ giá trị trả về của TakeAndGiveInt. Vì vậy, không có thêm bí ẩn được thêm vào bởi trường hợp ConsumeFunc1Func2. – Baldrick
Tôi sẽ có một đọc tốt về phần 7.5.2 của spec C# 4.0. Nó khá dễ đọc và mô tả các giai đoạn suy luận kiểu khác nhau và cách chúng liên quan đến các nhóm phương pháp. – Baldrick
'ConsumeFunc2b' cho thấy rằng đối với' Func , T> 'kiểu trả về' T' có thể được giải quyết từ 'TakeAndGiveInt'. Nhưng khi '?' Cũng là 'T' như trường hợp với' Func 'trong' ConsumeFunc2c', trình dịch dường như quên tham số 'T' giống với' T 'đã suy ra. Khá khác với thành công 'ConsumeFunc1Func2'. –