C#4.0以及可选参数和重载的组合是否会对歧义性发出警告?

C#4.0以及可选参数和重载的组合是否会对歧义性发出警告?,c#,optional-parameters,overloading,ambiguity,C#,Optional Parameters,Overloading,Ambiguity,我已经开始阅读乔恩·斯基特(Jon Skeet)的早期access版本的书,其中包含关于C#4.0的章节,有一件事让我印象深刻。不幸的是,我没有VisualStudio2010,所以我想我应该在这里问一下,看看是否有人知道答案 如果我有以下代码,现有代码和新代码的混合: public void SomeMethod(Int32 x, Int32 y) { ... } public void SomeMethod(Int32 x, Int32 y, Int32 z = 0) { ... } 编

我已经开始阅读乔恩·斯基特(Jon Skeet)的早期access版本的书,其中包含关于C#4.0的章节,有一件事让我印象深刻。不幸的是,我没有VisualStudio2010,所以我想我应该在这里问一下,看看是否有人知道答案

如果我有以下代码,现有代码和新代码的混合:

public void SomeMethod(Int32 x, Int32 y) { ... }

public void SomeMethod(Int32 x, Int32 y, Int32 z = 0) { ... }
编译器会在定义站点或调用站点抱怨可能的歧义吗

例如,这段代码实际上会做什么

SomeClass sc = new SomeClass();
sc.SomeMethod(15, 23);

它会编译吗?它将调用不带z参数的函数,还是调用带z参数的函数?

它将在没有警告的情况下编译并选择第一个重载

随着可选参数和命名参数的引入,C#的过载解析机制变得非常复杂。然而,在这种特殊情况下,这是有意义的。与往常一样,编译器将选择与参数匹配的最具体的重载

我不认为这个具体案例与C#1.0有什么不同:

其工作原理相同(在过载分辨率方面)

跟进回答:我不这么认为。恐怕您必须在方法调用中手动指定默认参数。但是,如果
x
y
参数具有不同的名称,如:

public void SomeMethod(Int32 x, Int32 y) { } 
public void SomeMethod(Int32 t, Int32 y, Int32 z = 0) { }
您可以使用以下选项选择第二个重载:

obj.SomeMethod(t: 10, y: 20);
本章的“过载解决”一节介绍了这一点

当编译器有两个相等的选项可供选择时,它将使用一个重载,该重载不需要使用任何未应用的可选参数,而优先于使用任何未应用的可选参数,但它是一个严格的二进制选择。如果必须在一个超载和一个未提供的可选参数之间进行选择,那么它会认为这是一个模棱两可的情况。 为了回答您的后续评论,我不知道有什么方法可以在不指定可选参数的情况下强制使用带有可选参数的重载。您不能使用其中任何一个,例如:

// Both invalid
sc.SomeMethod(15, 23, );
sc.SomeMethod(15, 23, z:)
但是,如果您的方法使用不同的参数名称,则可以执行以下操作:

public void SomeMethod(Int32 x, Int32 y) { ... }
public void SomeMethod(Int32 a, Int32 b, Int32 c = 0) { ... }

sc.SomeMethod(a: 15, b: 23); // Calls second method

后续问题:有没有办法在不指定
z
参数的情况下调用第二个重载?撇开这个具体问题不谈,我很高兴收到关于新章节的任何其他反馈-通过类似问题或直接通过电子邮件(skeet@pobox.com). 希望你喜欢这些新东西:)在我发送任何反馈或问题之前,我会先阅读我下载的文件;)但我很乐意提供反馈。周末我会把文件带到一个没有互联网的房子里,所以我可能会深入研究一下。
public void SomeMethod(Int32 x, Int32 y) { ... }
public void SomeMethod(Int32 a, Int32 b, Int32 c = 0) { ... }

sc.SomeMethod(a: 15, b: 23); // Calls second method