方法签名中的 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)
    { }
}

方法签名中的 ICollection[]

方法调度是基于变量类型而不是运行时类型完成的。 这在 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 引用展开形式的参数 参数列表的形式。