Vâng, bạn đã bỏ qua phần quan trọng nhất khiến mọi thứ hoạt động. Các thông số loại có thể được suy ra bởi các thông số đối tượng thực tế được thông qua vào
Ví dụ:.
static class Extensions {
internal static IEnumerable<U> Test<T, U>(
this IEnumerable<T> items,
Func<T, U> converter) {
foreach (T item in items) {
yield return converter(item);
}
}
}
Phần mở rộng này phương pháp hoạt động trên bất kỳ lớp IEnumerable và sẽ chuyển đổi từng mục trong kiểu liệt kê để một loại dựa trên bộ chuyển đổi bạn đã cung cấp. Đây là generics tiêu chuẩn.
Bây giờ, có rất nhiều cách để gọi phương pháp này:
IEnumerable<int> values = Enumerable.Range<int>(1, 10);
Func<int, string> converter = i => i.ToString("0.00");
// Variation 1, explicit calling
IEnumerable<string> results1 = Extensions.Test<int, string>(values, converter);
// Variation 2, explicit calling with type inference
IEnumerable<string> results2 = Extensions.Test(values, converter);
// Variation 3, extension method calling, still providing explicit types
IEnumerable<string> results3 = values.Test<int, string>(converter);
// Variation 4, extension method with type inference
IEnumerable<string> results4 = values.Test(converter);
Tất cả bốn biến thể gọi phương thức tương tự và trả lại kết quả tương tự. Loại suy luận hoạt động bằng cách xem xét các tham số được truyền và tự động suy ra loại của chúng dựa trên những gì được cung cấp. Trong ví dụ trên, chúng tôi có thể xác định rằng loại T
thuộc loại int
vì chúng tôi đã nhập số IEnumerable<int>
vào thông số cho IEnumerable<T>
. Cũng có thể suy ra rằng loại U
thuộc loại string
vì chúng tôi đã chuyển vào Func khớp với loại ban đầu là T
với int
và trả về một chuỗi. Vì vậy, Func<T, U>
được điền vào với chức năng chuyển đổi của chúng tôi là Func<int, string>
.
Từ suy luận ở trên, đó là phương pháp chung chuẩn ở thời điểm đó. Loại suy luận và phương pháp mở rộng là không có gì nhiều hơn đường tiện lợi/cú pháp.Trong thực tế, nếu bạn dịch ngược đầu ra, bạn có thể thấy rằng các phương thức mở rộng được thay thế bằng các cuộc gọi tĩnh và thường được định nghĩa với các tham số kiểu được điền một cách rõ ràng. (Điều này thay đổi dựa trên bộ giải mã của bạn và các tùy chọn thiết lập).
Tôi có thể trả lời # 1 đơn giản là đủ. Nó cho phép phương thức làm việc với bất kỳ loại bộ sưu tập nào, thay vì chỉ làm việc cho các chuỗi hoặc int hoặc Foos hoặc bất kỳ thứ gì. Nó cũng cho phép bạn so sánh với bất kỳ loại giá trị nào, cho phép nó là một int hoặc một chuỗi hoặc một Bar hoặc [...]. Trong trường hợp cụ thể của bạn, bạn chỉ cần chọn một 'int' từ một mảng của một số loại (mà tôi thậm chí không biết tên của tâm trí bạn). Sử dụng Generics nó sẽ làm việc không chỉ cho một trường hợp của bạn, nhưng bất kỳ trường hợp tương tự có cùng một vấn đề nhưng với các loại khác nhau. Điều này sẽ hữu ích hơn cho những khách truy cập trong tương lai tìm câu hỏi của bạn. – Servy
@Servy thanks! Đối với người đọc trong tương lai, tôi cũng tìm thấy bài đăng này: http://stackoverflow.com/questions/4885027/how-does-generic-type-inference-work-in-c –