C#4.0以及可选参数和重载的组合是否会给出关于模糊性的警告?
-
06-07-2019 - |
题
我开始阅读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
不隶属于 StackOverflow