2012-03-27 27 views
7

Với chữ ký phương thức sau, tại sao khi tham số được đặt tên rõ ràng, trình biên dịch không thể tự động suy ra kiểu? Visual Studio 2010 SP1 có thể suy ra loại và không hiển thị cảnh báo hoặc lỗi.Không thể suy ra kiểu generic với các tham số tùy chọn

IEnumerable<T> ExecuteCommand<T>(
    string commandText, 
    string connectionName = null, 
    Func<IDataRecord, T> converter = null) { ... } 

static SomeClass Create(IDataRecord record) { return new SomeClass(); } 

void CannotInferType() { 
    var a = ExecuteCommand(
     "SELECT blah", 
     "connection", 
     converter: Test.Create); 
} 

void CanInferType() { 
    var a = ExecuteCommand(
     "SELECT blah", 
     "connection", 
     Test.Create); 
} 

Gọi nó như được mô tả trong CannotInferType và khi cố gắng để biên dịch nó trình biên dịch phát ra error CS0411: The type arguments for method 'Test.ExecuteCommand<T>(string, string, System.Func<System.Data.IDataRecord,T>)' cannot be inferred from the usage. Try specifying the type arguments explicitly. Trong khi gọi nó như được mô tả trong CanInferType công trình như mong đợi.

Như đã nêu ở trên, Visual Studio tự báo cáo không có vấn đề, và intellisense cho biến a hiển thị IEnumerable<SomeClass> như mong đợi nhưng vì một số lý do nó không biên dịch.

+0

Nó sẽ giúp ích nếu bạn đưa ra một ví dụ ngắn nhưng * hoàn thành * ... –

Trả lời

7

Đó là lỗi trong trình biên dịch C# 4. Nó đã được sửa trong trình biên dịch C# 5.

Tôi nghi ngờ đây không phải là tham số tùy chọn gây ra sự cố ở đây - đó là đối số được đặt tên. Hãy thử xóa các giá trị mặc định cho các thông số của bạn và tôi nghi ngờ bạn vẫn sẽ gặp sự cố tương tự. (Nó có giá trị khác biệt giữa các thông số tùy chọn và các đối số được đặt tên - chúng là hai tính năng riêng biệt. Chúng thường được sử dụng cùng nhau, nhưng chắc chắn không phải là.)

Đó là kết luận mà tôi đã đưa ra khi tôi gửi lỗi này báo cáo cho Eric và Mads:

using System; 

class Test 
{ 
    static void Foo<T>(Func<T> func) {} 

    static void Main() 
    { 
     // Works fine 
     Foo(() => "hello"); 

     // Type inference fails 
     Foo(func:() => "hello"); 
    } 
} 

Happily này ngay bây giờ làm việc trong trình biên dịch beta C# 5.

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