我开始阅读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) { ... }

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

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

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

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

有帮助吗?

解决方案

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

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

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

public void SomeMethod(Int32 x, Int32 y) { } 
public void SomeMethod(Int32 x, Int32 y, params Int32[] z) { }

的工作方式相同(在重载分辨率方面)。

跟进回答:我不这么认为。我担心你必须在方法调用中手动指定默认参数。但是,如果 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
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top