首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >与泛型和IEnumerable相关的方法重载解析

与泛型和IEnumerable相关的方法重载解析
EN

Stack Overflow用户
提问于 2011-02-06 06:08:37
回答 2查看 1.5K关注 0票数 19

前几天我注意到这一点,假设你有两个重载的方法:

代码语言:javascript
复制
public void Print<T>(IEnumerable<T> items) {
    Console.WriteLine("IEnumerable T"); 
}
public void Print<T>(T item) {
    Console.WriteLine("Single T"); 
}

这段代码:

代码语言:javascript
复制
public void TestMethod() {  
    var persons = new[] { 
        new Person { Name = "Yan", Age = 28 },
        new Person { Name = "Yinan", Age = 28 } 
    };  
    Print(persons);
    Print(persons.ToList()); 
}

打印:

代码语言:javascript
复制
Single T
Single T

为什么在这些情况下,Person[]List<Person>T的匹配度要高于与IEnumerable<T>的匹配度?

谢谢,

更新:也是,如果你有另一个重载

代码语言:javascript
复制
public void Print<T>(List<T> items) {
    Console.WriteLine("List T");
}

Print(persons.ToList());实际上将打印List T而不是Single T

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-02-06 07:14:37

问题的第一部分(没有特定于列表的重载)很简单。让我们考虑一下Array调用,因为它对于两个调用都是一样的:

首先,类型推断生成该调用的两种可能的泛型实现:Print<Person[]>(Person[] items)Print<Person>(IEnumerable<Person> items)

然后重载解析开始生效,第一个重载解析获胜,因为第二个需要隐式转换,而第一个不需要(参见C#规范的§7.4.2.3 )。同样的机制也适用于列表变体。

使用添加的重载,使用列表调用生成第三个可能的重载:Print<Person>(List<Person> items)。该参数与Print<List<Person>>(List<Person> items)相同,但7.4.3.2节提供了包含该语言的解决方案

递归地,如果至少有一个类型参数比另一个类型参数更具体,并且没有类型参数比另一个类型参数更具体,则构造的类型比另一个构造的类型(具有相同数量的类型参数)更具体。

因此,Print<Person>重载比Print<List<Person>>重载更具体,列表版本胜过IEnumerable,因为它不需要隐式转换。

票数 18
EN

Stack Overflow用户

发布于 2011-02-06 06:13:12

因为从泛型Print(Person[] item)Print(List<Person> item)生成的方法比IEnumerable<T>更匹配。

编译器根据您的类型参数生成这些方法,因此通用模板Print<T>(T item)将编译为Print(Person[] item)Print(List<Person> item) (好吧,无论编译时表示List<Person>的是什么类型)。因此,编译器会将方法调用解析为接受直接类型的特定方法,而不是Print(IEnumerable<Peson>)的实现。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4910018

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档