方法签名中的 ICollection[]
本文关键字:ICollection 方法 | 更新日期: 2023-09-27 18:30:14
我有以下代码。为什么它总是采用"采取(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)
{ }
}
方法调度是基于变量类型而不是运行时类型完成的。 这在 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);
}
参见: 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 引用展开形式的参数 参数列表的形式。