一段时间以来,我一直在使用 .NET 4 以有限的方式使用可选参数。我最近思考了可选参数是如何实现的,我突然想到了一些东西。
举个例子:
public interface ITest
{
void Go(string val = "Interface");
}
实现这一点的唯一要求是实现最大形式的签名void Go (string val)
,实际上我们不需要实现可选参数,因为编译器会处理该连接(尽管使用可选参数的选项在使用时不可用直接的具体类)。
话虽如此,为了在两个地方都提供功能,并使其在实现中可发现,可以在接口和实现中实现可选声明。事实上,生产力工具 ReSharper 会在实现接口时自动将此可选声明拉到具体类型。这似乎是合乎逻辑的事情。然而...
是什么阻止我们在具体类型和接口中使用不同的值?这在今天早上敲响了我的警钟,好像有人进去更改该值,却忘记将其保留在覆盖/接口的继承中,行为将完全不同,具体取决于您访问对象的方式。调试起来可能非常令人沮丧。
试试这个 LINQpad 脚本:
void Main()
{
IA iface = new A();
A cls = new A();
iface.Go();
cls.Go();
}
interface IA
{
void Go(string val = "Interface");
}
class A : IA
{
public void Go(string val = "Class") { val.Dump(); }
}
输出将是:
Interface
Class
这让我想到了我的实际问题:
问题:
我们可以用什么(如果有的话?)方法来保护它,而不会失去使用具体类中的可选参数变体的能力,因此它对编码器来说是可发现/可读的?
有没有人遇到过这个问题?你是怎么解决的?是否有任何最佳实践可以帮助防止这个问题在多开发人员大规模代码库中变得普遍?