3

Why doesn't the C# compiler get confused about methods that have default arguments?

In the below code SayHello() may refer to:

  • SayHello()
  • SayHello(string arg1 = null)
  • SayHello(string arg1 = null, string arg2 = null)
  • SayHello(string arg1 = null, string arg2 = null, string arg3 = null)

But this code compiles successfully without any ambiguous errors.

class Program
{
    private static void SayHello()
    {
        Console.WriteLine("Hello 1");
        return;
    }

    private static void SayHello(string arg1 = null)
    {
        Console.WriteLine("Hello 2");
        return;
    }

    private static void SayHello(string arg1 = null, string arg2 = null)
    {
        Console.WriteLine("Hello 3");
        return;
    }

    private static void SayHello(string arg1 = null, string arg2 = null, string arg3 = null)
    {
        Console.WriteLine("Hello 3");
        return;
    }

    private static void Main(string[] args)
    {
        SayHello(); // SayHello() invoked, but SayHello(string arg1 = null) not invoked.
        SayHello("arg1");
        SayHello("arg1", "arg2", "arg3");

        // Output is:
        // Hello 1
        // Hello 2
        // Hello 3

        return;
    }
}
4

3 回答 3

9

编译器将首先选择没有任何可选参数的方法。因此,就编译器而言,您的代码中没有歧义。

于 2013-05-15T15:54:55.143 回答
6

为什么 C# 编译器不会混淆具有默认参数的方法?

这个问题无法回答。一个可以回答的问题是:

如果我想了解重载解析如何处理默认参数,我应该阅读 C# 语言规范的哪一部分?

获取 C# 4 规范的副本;您可以下载它或购买带注释的纸质版本。您要阅读的部分是 7.5.1“参数列表”和 7.5.3“重载解决方案”。特别参见第 7.5.3.2 节“更好的函数成员”。

描述您所看到的行为的确切行是:

如果 Mp 的所有参数都有对应的参数,而默认参数需要替换 Mq 中的至少一个可选参数,则 Mp 优于 Mq。

于 2013-05-15T16:01:47.480 回答
4

编译器有规则(在此处详述)来选择正确的重载

于 2013-05-15T15:56:27.487 回答