方法签名中的ICollection []

Hel*_*lic 1 c# signature

我有以下代码.为什么总是采用"采取(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)
    { }
}
Run Code Online (Sandbox Code Playgroud)

Ree*_*sey 7

方法调度基于变量类型而不是运行时类型完成.这在C#语言规范7.5.3(重载分辨率)中有详细介绍 - 在整个部分中没有任何地方建议使用变量的运行时类型.调度由编译器根据"参数表达式"处理:

给定一个参数列表A,其中包含一组参数表达式{E1,E2,...,EN}和两个适用的函数成员MP和MQ,参数类型为{P1,P2,...,PN}和{Q1,Q2, ...,QN},MP被定义为比MQ更好的函数成员if

•对于每个参数,从EX到QX的隐式转换并不比从EX到PX的隐式转换更好

•对于至少一个参数,从EX到PX的转换优于从EX到QX的转换.

如果您想要动态调度,可以通过以下方式完成dynamic:

 foreach (ICollection<String> a in ary)
 {
     dynamic o = a;
     p.take(o);
 }
Run Code Online (Sandbox Code Playgroud)

或者,更短的形式:

 foreach (dynamic a in ary)
 {
     p.take(a);
 }
Run Code Online (Sandbox Code Playgroud)