我有以下代码。为什么总是采用“采取(ICollection a)”方法?我认为它自己的对象应该是LinkedList或HashSet,所以它应该调用另外两个take方法。
class Program
{
static void Main(string[] args)
{
Program p = new Program();
ICollection<String>[] ary = { new LinkedList<String>(), new HashSet<String>() };
foreach (ICollection<String> a in ary)
{
p.take(a);
}
for (int i = 0; i < ary.Length; i++)
{
p.take(ary[i]);
}
}
public void take(HashSet<String> a)
{ }
public void take(LinkedList<String> a)
{}
public void take(ICollection<string> a)
{ }
}
答案 0 :(得分:7)
方法调度是基于变量类型而不是运行时类型完成的。这在C#语言规范7.5.3(重载分辨率)中有详细介绍 - 在整个部分中没有任何地方建议使用变量的运行时类型。调度由编译器根据“参数表达式”处理:
给定一个参数列表A,其中包含一组参数表达式{E1,E2,...,EN}和两个适用的函数成员MP和MQ,其参数类型为{P1,P2,...,PN}和{Q1 ,Q2,...,QN},MP被定义为比MQ更好的函数成员
•对于每个参数,从EX到QX的隐式转换并不比从EX到PX的隐式转换更好,并且
•对于至少一个参数,从EX到PX的转换优于从EX到QX的转换。
如果您希望动态发送,可以通过dynamic
:
foreach (ICollection<String> a in ary)
{
dynamic o = a;
p.take(o);
}
或者,更短的形式:
foreach (dynamic a in ary)
{
p.take(a);
}
答案 1 :(得分:2)
请参阅:http://msdn.microsoft.com/en-us/library/aa691336(v=vs.71).aspx
http://msdn.microsoft.com/en-us/library/aa691338(v=vs.71).aspx
来自MSDN:
给定一个参数列表A,其中包含一组参数类型{A1,A2,..., AN}和两个适用的函数成员MP和MQ以及参数类型 {P1,P2,...,PN}和{Q1,Q2,...,QN},MP定义为更好 函数成员比MQ如果:
- 对于每个参数,从AX到PX的隐式转换并不比从AX到QX的隐式转换更差,并且
- 对于至少一个参数,从AX到PX的转换优于从AX到QX的转换。
执行此评估时,如果MP或MQ适用于其中 扩展形式,然后PX或QX指的是扩展中的参数 参数列表的形式。