C#4.0默认参数

考虑以下控制台应用程序:

class Program
{
    static void Main()
    {
        MyInterface test = new MyClass();
        test.MyMethod();

        Console.ReadKey();
    }
}

interface MyInterface
{
    void MyMethod(string myString = "I am the default value on the interface");
}

class MyClass : MyInterface
{
    public void MyMethod(string myString = "I am the default value set on the implementing class")
    {
        Console.WriteLine(myString);
    }
}

该程序的输出是:

I am the default value on the interface

(1)为什么没有在没有提供值的情况下在接口上指定参数为可选的方法.我认为认值是实现细节.如果我们以pre-optional参数样式编写此代码,我们将在接口中创建两个重载,并在实现类中指定认值.即我们会有:

interface MyInterface
{
    void MyMethod();

    void MyMethod(string myString);
}

class MyClass : MyInterface
{
    public void MyMethod()
    {
        MyMethod("I am the default value set on the implementing class");
    }

    public void MyMethod(string myString)
    {
        Console.WriteLine(myString);
    }
}

哪个输出正如我们所料,

I am the default value set on the implementing class

(2)为什么我们不能覆盖实现类中的认值!

解决方法

.Net中的认值实际上是基于编译器的语法糖.在调用站点,编译器会为您添加认值.它无法在编译时知道对象的运行时类型,因此必须插入接口中定义的值.

因此,它们不能在实现中被“覆盖”,因为没有什么可以覆盖.

Eric Lippert撰写了一系列关于可选参数主题的非常有趣的博客文章,其中第一篇可以找到here.

更新
根据您的评论,您建议的是某种形式的“虚拟”参数(运行时类型声明),CLR必须“知道”.我猜这个实现被排除了,因为成本(设计,记录,实施,测试等)与它给出的好处相比太高了(虽然这只是猜测!).
或者,有认的委托方法选项,即:

void M(bool y = false) { ... whatever ... }

由编译器重写为:

void M() { M(false); }
void M(bool y) { ... whatever ... }

但是,一旦考虑了多个可选参数和命名参数,那么沿着这条路线导致潜在的不可接受的重载级别.

相关文章

目录简介使用JS互操作使用ClipLazor库创建项目使用方法简单测...
目录简介快速入门安装 NuGet 包实体类User数据库类DbFactory...
本文实现一个简单的配置类,原理比较简单,适用于一些小型项...
C#中Description特性主要用于枚举和属性,方法比较简单,记录...
[TOC] # 原理简介 本文参考[C#/WPF/WinForm/程序实现软件开机...
目录简介获取 HTML 文档解析 HTML 文档测试补充:使用 CSS 选...