3

我尝试了以下代码:

class Program: ProgParent
    {

        public int Max(params int[] op)
        {
            return 0;
        }

        public int Max(int i, params int[] op)
        {
            return 1;
        }

        public int Max(int i, int j, params int[] op)
        {
            return 2;
        }

        public static void Main(string[] args)
        {
            System.Console.WriteLine((new Program()).Max(5, 6, 7, 8));
            System.Console.ReadKey();
        }
    }

它执行并使用最具体的可用功能。但是编译器对此没有给出警告或错误。为什么?

4

2 回答 2

4

C# 语言规范说:

在执行重载决议时,带有参数数组的方法可以以它的正常形式[即传递一个数组]或它的扩展形式[即传递可变数量的参数]适用。方法的扩展形式仅在方法的正常形式不可用并且仅当与扩展形式具有相同签名的方法尚未在相同类型中声明时才可用"

简而言之(稍微简化):如果重载决议不明确,编译器会选择非参数重载。

我猜这个决定的原因(而不是让像你这样的代码非法)包括:

  • 如果您的方法具有签名:void fn(params object[] p),您希望有某种方式来调用“正常形式”(通过传递 object[])。所以编译器无论如何都必须处理模棱两可的情况。
  • Creating a temporary array is a lot more expensive than a method call, so you might want to create non-params overloads with 1,2,3 parameters that behave the same but are more efficient. (like e.g. String.Format)
于 2009-03-31T07:44:16.620 回答
2

忽略构建错误(我将其归结为拼写错误)-您期望或想要什么警告?它正在寻找匹配的重载并使用它......

严格来说,我可以调用不同的重载——通过传递数组,但是是的,用法并不完全清楚。

如果没有多个重载 with params,这种模式在诸如string.Concatetc 之类的东西中被大量使用(它支持+引擎盖下的字符串)。

于 2009-03-31T07:08:21.497 回答