2013-12-18 16 views
9

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?

+0

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

+1

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

+0

'ConsumeFunc2b' cho thấy rằng đối với' Func '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'. –

Trả lời

1

Thông số phương pháp không được kiểm tra.

Như được đề xuất, trong ConsumeFunc1Func2 trình biên dịch chỉ suy ra từ các giá trị trả lại. Trong ConsumeFunc2c, chữ ký TakeAndGiveInt không được kiểm tra để xem kiểu tham số phương thức của nó có thực sự thuộc cùng kiểu kiểu phương thức trả về nguyên nhân ... các tham số phương thức không được kiểm tra không!

1

Nói chung, tên phương thức sẽ không xác định duy nhất một loại duy nhất Action<T> mà nhóm phương pháp có thể được chỉ định. Ví dụ: ngay cả khi chỉ có một quá tải là Fred và phải có một đối số Cat đơn lẻ, quá tải đó có thể được gán không chỉ cho một số Action<Cat> mà còn đối với một số loại khác như Action<Mammal>, Action<Animal> hoặc Action<Object>. Trong khi có một số trường hợp mà một sự thay thế loại sẽ theo mọi cách vượt trội so với bất kỳ sự thay thế nào khác, điều đó không phải luôn luôn như vậy. Đó là sạch hơn để xác định ngôn ngữ để yêu cầu loại đại biểu được chỉ định, hơn là có trình biên dịch cố gắng "đoán", đặc biệt là vì việc đoán trình biên dịch có nghĩa là nhiều thứ không nên phá vỡ thay đổi, thêm một phương thức quá tải có thể làm cho một loại suy luận không rõ ràng được sử dụng để làm việc).

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