C#4.0以及可选参数和重载的组合是否会给出关于模糊性的警告?

ang*_*son 6 c# overloading ambiguity optional-parameters

我开始阅读Jon Skeet的早期访问版本,其中包含有关C#4.0的部分,有一件事让我感到震惊.不幸的是我没有Visual Studio 2010可用,所以我想我只是在这里问一下,看看是否有人知道答案.

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

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

public void SomeMethod(Int32 x, Int32 y, Int32 z = 0) { ... }
Run Code Online (Sandbox Code Playgroud)

编译器是否会在定义站点或呼叫站点上抱怨可能的歧义?

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

SomeClass sc = new SomeClass();
sc.SomeMethod(15, 23);
Run Code Online (Sandbox Code Playgroud)

它会编译吗?它会调用没有z参数的那个,还是会调用带z参数的那个?

Jon*_*eet 9

本章的"过载分辨率"部分对此进行了介绍.

当编译器有两个相同的选项可供选择时,它将使用一个重载,它不需要使用任何不匹配的可选参数而不是那个,但它是一个严格的二元选择.如果必须在具有一个未提供的可选参数的过载和两个之间进行选择,则会认为这是一个模糊的情况.

要回答你的后续评论,我不知道在没有指定的情况下使用可选参数强制重载的任何方法.您不能使用其中任何一个,例如:

// Both invalid
sc.SomeMethod(15, 23, );
sc.SomeMethod(15, 23, z:)
Run Code Online (Sandbox Code Playgroud)

但是,如果您的方法使用不同的参数名称,则可以执行以下操作:

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
Run Code Online (Sandbox Code Playgroud)


Meh*_*ari 6

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

随着可选和命名参数的引入,C#的重载解析机制变得非常复杂.在这种特定情况下,它是有道理的.像往常一样,编译器将选择与参数匹配的最具体的重载.

我不相信这个具体案例与C#1.0有很大不同:

public void SomeMethod(Int32 x, Int32 y) { } 
public void SomeMethod(Int32 x, Int32 y, params Int32[] z) { }
Run Code Online (Sandbox Code Playgroud)

它的工作方式相同(就重载分辨率而言).

跟进回答:我不这么认为.我担心你必须在方法调用中手动指定默认参数.但是,如果xy参数具有不同的名称,例如:

public void SomeMethod(Int32 x, Int32 y) { } 
public void SomeMethod(Int32 t, Int32 y, Int32 z = 0) { }
Run Code Online (Sandbox Code Playgroud)

您可以选择第二个重载:

obj.SomeMethod(t: 10, y: 20);
Run Code Online (Sandbox Code Playgroud)