方法签名中的ICollection []

时间:2013-09-05 16:13:33

标签: 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)
    { }
}

2 个答案:

答案 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指的是扩展中的参数   参数列表的形式。