5

Tôi vừa nhận thấy một hành vi lạ với độ phân giải quá tải.Quá tải, suy luận kiểu chung và từ khóa 'params'

Giả sử rằng tôi có phương pháp sau đây:

public static void DoSomething<T>(IEnumerable<T> items) 
{ 
    // Whatever 

    // For debugging 
    Console.WriteLine("DoSomething<T>(IEnumerable<T> items)"); 
} 

Bây giờ, tôi biết rằng phương pháp này sẽ thường được gọi với một số lượng nhỏ các lập luận rõ ràng, vì vậy để thuận tiện tôi thêm tình trạng quá tải này:

public static void DoSomething<T>(params T[] items) 
{ 
    // Whatever 

    // For debugging 
    Console.WriteLine("DoSomething<T>(params T[] items)"); 
} 

Bây giờ tôi cố gắng gọi những phương pháp:

var items = new List<string> { "foo", "bar" }; 
DoSomething(items); 
DoSomething("foo", "bar"); 

Nhưng trong cả hai trường hợp, quá tải với params được gọi. Tôi đã mong đợi sự quá tải IEnumerable<T> để được gọi trong trường hợp của List<T>, bởi vì nó có vẻ phù hợp hơn (ít nhất là với tôi).

Hành vi này có bình thường không? Bất cứ ai có thể giải thích nó? Tôi không thể tìm thấy bất kỳ thông tin rõ ràng về điều đó trong tài liệu MSDN ... Quy tắc giải quyết quá tải có liên quan ở đây là gì?

Trả lời

9

Mục 7.4.3 của đặc điểm kỹ thuật C# 3.0 là bit liên quan tại đây. Về cơ bản các mảng tham số được mở rộng, vì vậy bạn đang so sánh:

public static void DoSomething<T>(T item) 

public static void DoSomething<T>(IEnumerable<T> item) 

Các T cho trận đấu đầu tiên được suy ra được List<string>T cho trận đấu thứ hai được suy ra được string.

Bây giờ, hãy xem xét các chuyển đổi có liên quan đến đối số cho loại tham số - trong trường hợp đầu tiên là List<string> đến List<string>; trong giây thứ hai, nó là List<string> đến IEnumerable<string>. Chuyển đổi đầu tiên là tốt hơn so với lần thứ hai theo các quy tắc trong 7.4.3.4.

Bit phản trực giác là suy luận kiểu. Nếu bạn lấy nó ra khỏi phương trình, nó sẽ hoạt động như bạn mong đợi nó:

var items = new List<string> { "foo", "bar" }; 
DoSomething<string>(items); 
DoSomething<string>("foo", "bar"); 

Tại thời điểm đó, chỉ có một thành viên chức năng áp dụng trong mỗi cuộc gọi.

+0

Cảm ơn Jon, đó chính là lời giải thích mà tôi cần. Có một số cách giải quyết để làm cho nó hoạt động như tôi muốn không? Nếu không, tôi đoán tôi sẽ phải sử dụng một tên khác ... –

+0

Có, tôi nhận thấy rằng nó hoạt động nếu tôi chỉ định tham số kiểu chung chung một cách rõ ràng. Nhưng tôi đánh mất lợi ích của suy luận kiểu ... –

+4

Tôi sẽ đề nghị sử dụng một tên khác, chỉ để cho rõ ràng - hoặc nếu bạn chỉ sử dụng nó với nhiều hơn một mục, bạn có thể làm '(T đầu tiên, params T [] những người khác) ' –

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