重载,泛型类型推理和'参数'关键字 [英] Overloading, generic type inference and the 'params' keyword
问题描述
我只注意到与重载一个奇怪的行为
I just noticed a strange behavior with overload resolution.
假设我有以下方式:
public static void DoSomething<T>(IEnumerable<T> items)
{
// Whatever
// For debugging
Console.WriteLine("DoSomething<T>(IEnumerable<T> items)");
}
现在,我知道,这种方法往往会使用少量的被称为明确的参数,所以为了方便我添加此过载:
Now, I know that this method will often be called with a small number of explicit arguments, so for convenience I add this overload :
public static void DoSomething<T>(params T[] items)
{
// Whatever
// For debugging
Console.WriteLine("DoSomething<T>(params T[] items)");
}
现在我尝试调用这些方法:
Now I try to call these methods :
var items = new List<string> { "foo", "bar" };
DoSomething(items);
DoSomething("foo", "bar");
但在这两种情况下,用 PARAMS过载
被调用。我本来期望的的IEnumerable< T>
过载的列表与LT的情况下调用; T>
,因为它似乎是一个更好的匹配(至少对我来说)。
But in both cases, the overload with params
is called. I would have expected the IEnumerable<T>
overload to be called in the case of a List<T>
, because it seems a better match (at least to me).
这是正常的行为?谁能解释一下吗?我找不到关于在MSDN文档...什么是这里涉及的重载决议规则的任何明确的信息?
Is this behavior normal ? Could anyone explain it ? I couldn't find any clear information about that in MSDN docs... What are the overload resolution rules involved here ?
推荐答案
在C#3.0规范第7.4.3节是相关位在这里。基本参数数组扩大,所以你比较:
Section 7.4.3 of the C# 3.0 specification is the relevant bit here. Basically the parameter array is expanded, so you're comparing:
public static void DoSomething<T>(T item)
和
public static void DoSomething<T>(IEnumerable<T> item)
的
T
的第一场比赛被推断为列表<串>
和 T
对于第二场比赛被推断为字符串
The T
for the first match is inferred to be List<string>
and the T
for the second match is inferred to be string
.
现在考虑所涉及的参数参数类型的转换。 - 在第一个它的列表<串>
到列表<串>
;在第二个它的列表<串GT;
到的IEnumerable<串GT;
。第一次转换是7.4.3.4比第二的规则更好。
Now consider the conversions involved for argument to parameter type - in the first one it's List<string>
to List<string>
; in the second it's List<string>
to IEnumerable<string>
. The first conversion is a better than the second by the rules in 7.4.3.4.
有悖常理位是类型推断。如果你采取的方程,它会为你期望它的工作:
The counterintuitive bit is the type inference. If you take that out of the equation, it will work as you expect it to:
var items = new List<string> { "foo", "bar" };
DoSomething<string>(items);
DoSomething<string>("foo", "bar");
在这一点上,有一个在每次通话只有一个适用的函数成员。
At that point, there's only one applicable function member in each call.
这篇关于重载,泛型类型推理和'参数'关键字的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!