考虑以下控制台应用程序:
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)为什么我们不能覆盖实现类中的默认值!
答案 0 :(得分:4)
因此,它们不能在实现中被“覆盖”,因为没有什么可以覆盖。
Eric Lippert撰写了一系列关于可选参数主题的非常有趣的博客文章,其中第一篇可以找到here。
<强>更新强>
根据您的评论,您建议的是某种形式的“虚拟”参数(运行时类型声明),CLR必须“知道”。我猜这个实现被排除了,因为成本(设计,记录,实施,测试等)与它给出的好处相比太高了(虽然这只是猜测!)。
或者,有默认的委托方法选项,即:
void M(bool y = false) { ... whatever ... }
由编译器重写为:
void M() { M(false); }
void M(bool y) { ... whatever ... }
但是,一旦多个可选参数和命名参数被考虑在内,那么沿着这条路线导致潜在的不可接受的重载级别。
答案 1 :(得分:3)
1)你的想法存在缺陷。您说默认值是实现细节。接口没有实现细节。根据该逻辑,指定默认值实际上不属于接口。
使用重载方法编写接口。定义不仅更清晰,而且在与其他语言连接时界面更兼容,并且您不会遇到可选参数带来的版本问题。
2)因为界面定义了操作合同。界面说默认必须是......因此类必须以这种方式实现它。