6

我已经开始阅读 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 参数的那个?

4

2 回答 2

9

这在本章的“过载解决方案”部分中进行了介绍。

当编译器有两个其他相等的选项可供选择时,它将使用不需要使用任何未提供的可选参数的重载,而不是使用的重载,但这是一个严格的二元选择。如果它必须在具有一个未提供的可选参数和两个的重载之间进行选择,它将认为这是一种模棱两可的情况。

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

// 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
于 2009-07-31T08:02:07.797 回答
6

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

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

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

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

它的工作原理相同(就重载分辨率而言)。

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

public void SomeMethod(Int32 x, Int32 y) { } 
public void SomeMethod(Int32 t, Int32 y, Int32 z = 0) { }

您可以选择第二个重载:

obj.SomeMethod(t: 10, y: 20);
于 2009-07-31T07:56:35.217 回答