小编典典

为什么在接口上定义的 C# 4 可选参数未在实现类上强制执行?

all

我注意到使用 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 框架注入具体类),那么真的没有点具有默认值,因为调用者无论如何都必须始终提供它。


阅读 111

收藏
2022-03-22

共1个答案

小编典典

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

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


// 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 以使该方法具有可选参数?

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

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

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

提议的功能似乎给程序员增加了很多不便,但代表权并没有相应增加。这个特性有什么引人注目的好处,证明增加的用户成本是合理的?


更新:在下面的评论中,supercat 建议了一种语言功能,该功能可以真正增加语言的功能并启用一些类似于此问题中描述的场景。仅供参考,该功能 -
接口中方法的默认实现 - 将添加到 C# 8。

2022-03-22