我注意到,对于C#4中的可选参数,如果在接口上指定可选参数,则必须在任何实现类上使该参数可选:

public interface MyInterface
{
    void TestMethod(bool flag = false);
}

public class MyClass : MyInterface
{
    public void TestMethod(bool flag)
    {
        Console.WriteLine(flag);
    }
}

因此:

var obj = new MyClass();        
obj.TestMethod(); // compiler error

var obj2 = new MyClass() as MyInterface;
obj2.TestMethod(); // prints false

有人知道为什么可选参数设计成这样吗?

一方面,我认为覆盖接口上指定的任何默认值的能力是有用的,尽管说实话,我不确定您是否应该能够在接口上指定默认值,因为这应该是一个实现决策.

另一方面,这种分离意味着您不能总是交替使用具体类和接口.当然,如果在实现中指定了默认值,这不会是一个问题,但是如果您将您的具体类公开为接口(例如使用一些IOC框架来注入具体类),那么拥有默认值就没有意义,因为调用方无论如何都必须提供它.

推荐答案

更新:This question was the subject of my blog on May 12th 2011. Thanks for the great question!

假设您有一个如您所描述的接口,并有一百个实现它的类.然后,您决定将该接口的一个方法的参数设为可选.您是否建议编译器应该强制开发人员找到该接口方法的每个实现,并将参数设为可选?

假设我们这么做了.现在假设开发人员没有实现的源代码:


// in metadata:
public class B 
{ 
    public void TestMethod(bool b) {}
}

// in source code
interface MyInterface 
{ 
    void TestMethod(bool b = false); 
}
class D : B, MyInterface {}
// Legal because D's base class has a public method 
// that implements the interface method

《D》的作者应该如何做到这一点?在你的世界里,他们是否需要打电话给B的作者,并要求他们提供一个新版本的B,使该方法具有可选参数?

那不会飞的.如果有two人打电话给B的作者,其中一人希望默认值为真,另一人希望默认值为假,该怎么办?如果B的作者只是拒绝配合怎么办?

也许在这种情况下,他们会被要求说:

class D : B, MyInterface 
{
    public new void TestMethod(bool b = false)
    {
        base.TestMethod(b);
    }
}

提议的功能似乎给程序员增加了很多不便,但代表性的权力却没有相应增加.这项功能有什么令人信服的好处,可以为用户增加成本?


更新:在下面的 comments 中,supercat建议使用一种语言功能,它将真正增强语言的能力,并支持一些类似于本问题中描述的场景.仅供参考,该功能——接口中方法的默认实现——将添加到C#8中.

.net相关问答推荐

为什么.Net 8.0.100是预览版?

避免函数和其他对象之间的相互递归的模式?

无法使用 int.Parse 从字符串转换值

"投掷;" 是什么意思?靠自己做什么?

JavaScript 中的IsNullOrWhitespace?

发布版本中的 Debug.WriteLine

我可以从 .NET/C# 获取其他进程的命令行参数吗?

如何使用 log4net 记录跟踪消息?

如何从字符串中删除所有字母字符?

在 JavaScript 中使用 String.Format?

是否有 TLS 1.2 的 .NET 实现?

清除 .NET 的 StringBuilder 内容的最佳方法

为什么 System.Timers.Timer 能在 GC 中存活,而 System.Threading.Timer 不能?

是否有可用的 WPF 备忘单?

Find() 和 First() 抛出异常,如何改为返回 null?

.NET 的 XPath 和 XSLT 2.0?

如何将 MailMessage 对象作为 *.eml 或 *.msg 文件保存到磁盘

如果选中,则更改列表框项的 WPF DataTemplate

C# ListView 列宽自动

.NET 桌面应用程序中的 Settings.settings 与 app.config