2009-07-30 26 views
6

tôi có phương pháp sau đây:Làm thế nào để trình biên dịch C# suy ra các kiểu generic?

public TResult Get<TGenericType, TResult>() 
          where TGenericType : SomeGenericType<TResult> 
          where TResult : IConvertible { 
    //...code that uses TGenericType... 
    //...code that sets someValue... 
    return (TResult) someValue; 
} 

Ngay bây giờ, một người sử dụng của phương pháp này có sử dụng nó như thế này:

//Notice the duplicate int type specification 
int number = Get<SomeGenericType<int>, int>(); 

Tại sao tôi phải chỉ rõ TResult trong phương pháp defintion? Trình biên dịch đã biết TResult kể từ khi tôi chỉ định nó trong TGenericType. Lý tưởng nhất (nếu biên dịch C# là một thông minh hơn chút), phương pháp của tôi sẽ trông như thế này:

public TResult Get<TGenericType>() 
          where TGenericType : SomeGenericType<TResult> 
          where TResult : IConvertible { 
    //...code that uses TGenericType... 
    //...code that sets someValue... 
    return (TResult) someValue; 
} 

Vì vậy, người dùng chỉ đơn giản là có thể sử dụng nó như thế này:

//Much cleaner 
int number = Get<SomeGenericType<int>>(); 

Có cách nào để làm tôi muốn làm gì?

+0

Tôi nghĩ rằng việc xóa một số vòng loại như * stupid * khỏi mô tả câu hỏi sẽ giúp ích. – EFraim

+0

Đó là trình biên dịch ngu ngốc, phải không? ;) Tôi đã xóa bình luận không liên quan. Đây thực sự là một câu hỏi hợp lý mà không có nó. –

+0

Vì bạn đã được trả lời rằng không có cách nào để sử dụng chỉ một số thông số loại, có lẽ bạn nên cải cách câu hỏi của mình về những gì bạn muốn thực hiện. Như nó là viết tắt, câu hỏi của bạn là "làm thế nào để tôi làm cho trình biên dịch mã biên dịch C# vi phạm định nghĩa của ngôn ngữ C#?" Như vậy, nó phải được đóng lại là "không phải là một câu hỏi thực sự". –

Trả lời

8

Đặc tả C# không cho phép phỏng đoán một nửa đối số kiểu. Bạn nên cho trình biên dịch suy ra tất cả các đối số kiểu (không phải lúc nào cũng áp dụng được, như trong trường hợp của bạn) hoặc chỉ định tất cả chúng một cách thủ công.

CẬP NHẬT (trả lời nhận xét): Trong khi tôi không thuộc nhóm C# để đưa ra câu trả lời tuyệt đối cho câu hỏi của bạn, suy đoán của tôi là độ phức tạp của độ phân giải quá tải. nếu bạn đọc phần đó của đặc tả C#) sẽ tăng đáng kể nếu họ muốn cho phép một nửa các loại được phỏng đoán và một nửa không (đặc biệt là xem xét thực tế là bạn có thể quá tải các phương thức chỉ bằng số đối số chung).

+0

Nhưng tại sao họ chỉ định rằng trong đặc tả C#? Nó không giống như có bất cứ điều gì không an toàn về nó. –

+0

Xem xét một số quy tắc C++, bao gồm chuyên môn hóa một phần mẫu và cách các công cụ xác định truy cập hoạt động. Thông thường mọi thứ hoạt động suôn sẻ, nhưng có nhiều thứ đang rình rập ở đây và ở đó. Vì một trong những ý tưởng đằng sau Java và C# là để tránh biến chứng của C++, chấp nhận một chút bất tiện thay vào đó, điều này là đúng trong dòng. –

1

Nó phụ thuộc ...

Nếu bạn chỉ sử dụng SomeGenericType<TResult>, bạn có thể làm:

public TResult Get<TResult>() where TResult : IConvertible { 
    SomeGenericType<TResult> myInstance = ... 
    //...code that sets someValue... 
    return (TResult) someValue; 
} 

Không nhất thiết phải là một cách để đưa các loại đầu tiên trong đó, trong trường hợp này . Vì ví dụ của bạn không chuyển thành một tham số SomeGenericType<TResult> một cách rõ ràng như một tham số, nên nó cho thấy điều này là có thể.

Nếu không, bạn cần xác định hoàn toàn tất cả đối số chung của mình. Thật không may, đó chỉ là cách nó là trong C#.

+0

Chắc chắn, nhưng tôi cần sử dụng SomeGenericType trong phương pháp. Tôi sẽ cập nhật mã mẫu của mình để làm rõ điều đó. –

+0

Vâng, nhưng nhìn vào mã của tôi - miễn là nó không được thông qua như một tham số cho phương thức, bạn có thể sử dụng SomeGenericType trong phương thức (ví dụ: nếu bạn xây dựng một trong phương thức). Vì bạn biết TResult, điều này hoạt động tốt. Như tôi đã nói - nó có thể hoạt động trong một số trường hợp ... –

+0

Xin lỗi, tôi có nghĩa là tôi cần sử dụng TGenericType (xem mã mẫu đã cập nhật của tôi). –

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