the*_*onk 19 .net c# overloading overload-resolution
前几天我注意到这一点,说你有两个重载方法:
public void Print<T>(IEnumerable<T> items) {
Console.WriteLine("IEnumerable T");
}
public void Print<T>(T item) {
Console.WriteLine("Single T");
}
Run Code Online (Sandbox Code Playgroud)
这段代码:
public void TestMethod() {
var persons = new[] {
new Person { Name = "Yan", Age = 28 },
new Person { Name = "Yinan", Age = 28 }
};
Print(persons);
Print(persons.ToList());
}
Run Code Online (Sandbox Code Playgroud)
打印:
Single T
Single T
Run Code Online (Sandbox Code Playgroud)
在这些情况下,为什么Person[]
和他们相比List<Person>
更好?T
IEnumerable<T>
谢谢,
更新: 此外,如果你有另一个重载
public void Print<T>(List<T> items) {
Console.WriteLine("List T");
}
Run Code Online (Sandbox Code Playgroud)
Print(persons.ToList());
实际上会打印List T
而不是Single T
.
TTo*_*oni 18
问题的第一部分(没有特定于列表的重载)很容易.让我们考虑一下Array调用,因为它对两个调用都是一样的:
首先,类型推断产生两种可能的调用通用实现:Print<Person[]>(Person[] items)
和Print<Person>(IEnumerable<Person> items)
.
然后重载决策启动并且第一个获胜,因为第二个需要隐式转换,而第一个不需要(参见C#规范的第7.4.2.3节).相同的机制适用于List变体.
添加过载后,List调用会产生第三个可能的重载:Print<Person>(List<Person> items)
.该论点与第一Print<List<Person>>(List<Person> items)
部分相同,但第7.4.3.2节提供了该语言的解决方案
递归地,如果至少一个类型参数更具体,并且没有类型参数比另一个中的相应类型参数更不具体,则构造类型比另一个构造类型(具有相同数量的类型参数)更具体.
所以Print<Person>
重载比重载更具体Print<List<Person>>
,List版本胜过IEnumerable,因为它不需要隐式转换.