2013-02-26 34 views
9

Vì vậy, tôi chạy qua một câu trả lời bằng Servy (https://stackoverflow.com/a/15098242/496680) và một số mã của ông thực hiện điều này:gì đang ngụ ý kiểu generic thông số

public static int BinarySearch<TSource, TKey>(...) 

cho một phương pháp khuyến nông, nhưng ông gọi nó như thế này:

arr.BinarySearch(...) 

Tôi hỏi xung quanh và ai đó đã chứng minh rằng thông số loại chung được ngụ ý của nó. Tôi googled họ nhưng không tìm thấy thông tin về họ. Tôi hiểu làm thế nào generics làm việc nhưng tôi không hiểu làm thế nào/khi sử dụng chúng.

  1. Tại sao servy sử dụng chúng theo phương pháp gia hạn của mình?
  2. Có tên chính thức hơn cho những thứ mà tôi có thể tìm kiếm không?
+2

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

+0

@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 –

Trả lời

10

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).

+0

Đối với hai ví dụ cuối cùng của bạn, bạn cần bỏ qua 'giá trị' làm tham số. – Servy

+0

Rất tiếc, cảm ơn! Thật tuyệt vời những gì bạn có thể bỏ lỡ khi bạn không thể biên dịch! – Joshua

+0

Giải thích tuyệt vời! cảm ơn! –

2

Thuật ngữ tôi thường nghe là 'suy luận kiểu'.

+0

Có, nó được gọi là "suy luận kiểu". Có một ví dụ hoàn toàn cơ bản tại [Phương pháp chung (Hướng dẫn lập trình C#)] (http://msdn.microsoft.com/en-us/library/twcad0zb.aspx) nơi nó nói: _Bạn cũng có thể bỏ qua đối số kiểu và trình biên dịch sẽ ** suy luận ** nó. Các cuộc gọi sau đây để trao đổi là tương đương với các cuộc gọi trước đó: [...] Các quy tắc tương tự cho kiểu suy luận áp dụng cho phương pháp tĩnh và phương pháp dụ. Trình biên dịch có thể suy ra các tham số kiểu dựa trên các đối số phương thức mà bạn truyền vào; nó không thể suy ra các tham số kiểu chỉ từ một ràng buộc hoặc giá trị trả về. [...] _ –

6
  1. Ông sử dụng generic method trong trường hợp này vì nó cho phép phương pháp của mình hoạt động với bất kỳ loại nào có trong một số Collection<T>. Phương pháp chung làm cho điều này rất linh hoạt và có thể sử dụng được cho bất kỳ loại nào. Anh ta sử dụng kiểu inferrence khi gọi phương thức vì nó đơn giản hóa mã tại trang cuộc gọi.

  2. Xử lý tự động được gọi là Loại Inferrence và được đề cập chi tiết trong Đặc tả Ngôn ngữ C#, phần 7.5.2: Loại Inferrence. Nếu bạn muốn hiểu chi tiết, tôi khuyên bạn nên tải xuống C# language specification.

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