具有默认值的参数和在C#中具有类似签名的void - 编译器如何知道要调用哪个?

agi*_*iro 2 c# named-parameters

说我有以下简单的两种方法:

class Question
{
    public void MyMethod()
    {
        Console.WriteLine("no params here");
    }

    public void MyMethod(object o = null)
    {
        Console.WriteLine("an object here");
    }
}
Run Code Online (Sandbox Code Playgroud)

我这样调用一个:

new Question().MyMethod();
Run Code Online (Sandbox Code Playgroud)

它导致no params方法的调用,在这里写"没有params".

我知道我仍然可以打电话给对方,比如说

new Question().MyMethod(null);
Run Code Online (Sandbox Code Playgroud)

但我的问题是,为什么编译器不会警告我可能存在歧义或强迫我特别注意?它如何决定要拨什么电话?只是参数较少的那个?

Jon*_*eet 5

它如何决定要拨什么电话?

它适用于MS规范ECMA标准中的规则(请选择).超载是真的复杂-特别是你已经有了类型推断,继承,可选参数,无类型参数的时间(例如null,default,法团或lambda表达式)参与.

在这种情况下,它相对简单.这两种方法都适用,并且在参数转换方面都不比其他方法"更好",因为没有任何参数.然后是抢七规则 - 在这种情况下重要的是(ECMA版本):

如果没有发现函数成员更好,并且MP的所有参数都具有相应的参数,而缺省参数需要替换MQ中的至少一个可选参数,则MP优于MQ.否则,没有功能成员更好.

换句话说,它没有歧义,因为一个方法没有可选参数而没有相应的参数,而且一个方法没有.

请注意,这不是需要自动替换的"更少"可选参数的问题 - 它是"有没有".

作为一个例子,考虑:

class Question
{
    public void MyMethod(int x = 1) {}
    public void MyMethod(int x = 1, int y = 2) {}
}

class Test
{
    static void Main()
    {
        // Ambiguous
        new Question().MyMethod();
        // Unambiguous
        new Question().MyMethod(0);
    }        
}
Run Code Online (Sandbox Code Playgroud)

第一个调用(无参数)是不明确的,因为两个适用的方法都有可选参数而没有相应的参数.

第二呼叫(一个参数)挑选具有一个单一的参数的方法中,因为即使有一个可选参数,它有一个相应的参数-而具有两个参数的方法仍然存在没有对应的参数的可选参数.