为什么实现中允许的默认值与接口上定义的默认值不同?

本文关键字:默认值 定义 接口 实现 为什么 | 更新日期: 2023-09-27 18:11:21

我最近遇到了以下行为;

internal interface IOptionalParamTest
{
    void PrintMessage(string message = "Hello");
}
class OptionalParamTest : IOptionalParamTest
{
    public void PrintMessage(string message = "Goodbye")
    {
        Console.WriteLine(message);
    }
}
internal class Program
{
    static void Main()
    {
        IOptionalParamTest usingInterface = new OptionalParamTest();
        usingInterface.PrintMessage(); // prints "Hello"
        OptionalParamTest usingConcrete = new OptionalParamTest();
        usingConcrete.PrintMessage();// prints "Goodbye"
    }
}

我的问题是;为什么编译器不拒绝与接口上定义的默认值不同的PrintMessage的实现?

为什么实现中允许的默认值与接口上定义的默认值不同?

调用PrintMessage();只是语法上的糖。PrintMessage()方法没有接受零参数。编译器只插入正确的值。因此,编译器将第一个调用更改为:

PrintMessage("Hello");

因为usingInterface的编译时类型是IOptionalParamTest。

usingConcrete的编译时类型是OptionalParamTest,所以它在那里寻找要插入的值,调用变成

PrintMessage("Goodbye")

接口实现只是不使用默认值(相反:只有调用站点使用默认值);这在常规方法声明中是允许的,因此您仍然可以使用默认参数值特性-但不要求它是相同的值。如果我们添加一个显式接口实现,它会变得更有趣:

void IOptionalParamTest.PrintMessage(string message = "what happens here?")
{
    Console.WriteLine(message);
}

在回答"这里发生了什么?":编译器警告:

为形参'message'指定的默认值将不起作用,因为它适用于在不允许可选参数的上下文中使用的成员