C# 或多或少相等的重载

C# 或多或少相等的重载,c#,overloading,C#,Overloading,以下代码在C#4.0中编译: 编译器如何知道您正在调用哪个重载?如果不能,为什么代码仍然编译?在某些情况下。因此,您可能希望在这样的情况下使用不同的名称(或者在更有用的情况下:-)) 特别是,在四种情况中: Foo("bar"); Foo("bar", "bar"); Foo(new string[]{"bar", "bar"}); Foo("bar", new string[] { "bar", "bar" }); 只有#1和#

以下代码在C#4.0中编译:

编译器如何知道您正在调用哪个重载?如果不能,为什么代码仍然编译?

在某些情况下。因此,您可能希望在这样的情况下使用不同的名称(或者在更有用的情况下:-))

特别是,在四种情况中:

        Foo("bar");
        Foo("bar", "bar");
        Foo(new string[]{"bar", "bar"});
        Foo("bar", new string[] { "bar", "bar" });
只有#1和#2是“模糊的”(因为#3和#4自然分别匹配重载1和重载2)


在#1和#2的情况下,重载解析选择重载#2,因为它有一个独立的字符串参数,与调用的唯一/第一个参数匹配。

这在C语言规范第7.4.3.2章“更好的函数成员”中有很好的规定:

否则,如果MP在其正常形式下适用,而MQ有一个params数组,并且仅在其扩展形式下适用,则MP优于MQ

否则,如果MP的声明参数少于MQ,则MP优于MQ。如果这两个方法都有params数组,并且仅适用于它们的扩展形式,则会发生这种情况

Fwiw,C语言规范是一个非常可读的文档,可以帮助您自己解决这些难题。如果您的计算机上有它,请在vc\specifications\1033子目录中的Visual Studio安装目录(如c:\program files\microsoft Visual Studio 9.0)中找到它


另一个很好的例子是Ecma-335标准文档,它可以作为一个文件免费提供。它指定了CLR和JIT编译器的行为,这是理解C#(和CLR)为什么要这样做的好材料。推荐。

+1,一个有趣的问题,尽管可能已经在规范中给出了答案。有趣。如果我使用OP代码并调用
Foo(“one”)
编译器将选择第二个方法(vs2010、.net 4),根据该引用,这似乎是错误的。我调用第一个方法的唯一方法是传递一个字符串数组作为唯一的参数。@Fredrik:我的错误,错过了一条规则。谢谢,我知道规范,但我从来没有真正考虑过它(如果你知道我的意思的话)。当我有时间的时候,我会看看它,这样我就不会问这样的问题显得很愚蠢;-)@Jouke,你得到的选票已经超过了“愚蠢问题”的门槛。OT:你怎么会以一个弗里西亚人的名字和一条南方的河流作为姓氏呢?哦,是的,这是有道理的。我的意思是有这样两个重载不是很有用。
        Foo("bar");
        Foo("bar", "bar");
        Foo(new string[]{"bar", "bar"});
        Foo("bar", new string[] { "bar", "bar" });