我们采用以下扩展方法:
static class Extensions
{
public static bool In<T>(this T t, params T[] values)
{
return false;
}
}
我很好奇为什么这个代码编译并运行:
var x = new Object();
IEnumerable<int> p = new List<int> { 1, 2, 3 };
var t2 = x.In(p);
在In
内,values
为Object[]
,就像List<int>
即时转换为数组一样。对我而言,似乎params T[]
与IEnumerable<int>
不匹配,这就是为什么我甚至对此感到惊讶。
现在这段代码:
var x = 5;
IEnumerable<int> p = new List<int> { 1, 2, 3 };
var t2 = x.In(p);
不运行并生成编译器错误:
错误2参数2:无法转换 'System.Collections.Generic.IEnumerable'到'int []'
这是我对第一个实际上的期望。有人能解释一下这里发生了什么吗?谢谢!
答案 0 :(得分:40)
类型推断会将您的第一个电话转换为
In<object>(x, p);
此封闭式通用方法的参数为object, params object[]
因此,传递p
会将其隐式转换为object
,这将成为params数组中的单个项目。
您的第二个电话被推断(因为第一个参数)到
In<int>(x, p);
此处,第二个参数可以是int[]
(直接传递数组)或一系列int
s(通过params
)。
由于IEnumerable<int>
不属于那些,因此会出错。