几个月前,我用Java编写了一个简单的程序。
我有两个名为F的重载方法,其中一个采用可变长度参数。 这个程序不会编译,因为在main方法中调用F(4)是不明确的 编译器不知道选择哪种方法。
class Example
{
static void F(int... array)
{
Console.WriteLine("We are in first method");
}
static void F(int x, int ... array)
{
Console.WriteLine("We are in second method");
}
static void main()
{
F(4);
}
}
我在C#中编写了一个等效的程序,如下所示,我期待编译错误。 令人惊讶的是,程序编译成功没有任何错误。
程序的输出是“我们在第二种方法”,这意味着第二种方法 选择了重载方法!!!
这不奇怪吗?两种F方法都可以作为调用的候选者,但为什么CLR选择第二种重载方法???
class Example
{
static void F(params int[] array)
{
Console.WriteLine("We are in first method");
}
static void F(int x, params int[] array)
{
Console.WriteLine("We are in second method");
}
static void Main()
{
F(4);
}
}
答案 0 :(得分:3)
Params
也可以采用零参数,所以在这种情况下,当你调用F(4)
时,它假定参数没有被传递,因为4是int,所以调用相应的方法。
params关键字允许您指定采用a的方法参数 可变数量的参数。您可以发送以逗号分隔的列表 参数声明中指定的类型的参数,或者 指定类型的参数数组。你也可以发送否 参数。
答案 1 :(得分:0)
我相信它会选择第二种方法,因为你传递的是整数,而不是整数数组。
答案 2 :(得分:0)
C#采用这种方法,因为它在C#语言规范中这样说:
7.4.3.2更好的函数成员给定一个参数列表A,其中包含一组参数表达式{E1,E2,...,EN}和两个适用的函数 具有参数类型{P1,P2,...,PN}和{Q1的成员MP和MQ, Q2,...,QN},MP被定义为比MQ更好的函数成员
•对于每个参数,从EX到QX的隐式转换不是 比从EX到PX的隐式转换更好,
•对于至少一个参数,从EX到PX的转换优于 从EX转换为QX。执行此评估时,如果是MP或MQ 适用于其扩展形式,然后PX或QX指的是a 参数列表的扩展形式的参数。如果是 参数类型序列{P1,P2,...,PN}和{Q1,Q2,...,QN}是 相同的,按顺序应用以下打破平局规则 确定更好的功能成员。
•如果MP是非泛型方法而MQ是通用方法,则MP优于MQ。
• 否则,如果MP适用于其正常形式且MQ具有params数组且是 仅适用于其扩展形式,然后MP优于MQ。
• 否则,如果MP的声明参数少于MQ,则MP为 比MQ更好。如果两种方法都有params数组,则会发生这种情况 仅适用于其扩展形式。
•否则,如果MP有 比MQ更具体的参数类型,则MP优于MQ。让 {R1,R2,...,RN}和{S1,S2,...,SN}代表未实例化的和 MP和MQ的未扩展参数类型。 MP的参数类型更多 特定于MQ的if,对于每个参数,RX不是特定的 比SX,并且,对于至少一个参数,RX比SX更具体:
o类型参数的特定性不如非类型参数。
o递归地,构造的类型比另一个更具体 至少构造类型(具有相同数量的类型参数) 一个类型参数更具体,没有类型参数更少 特定于另一个中相应类型的参数。
o数组类型比另一种数组类型更具体(具有相同数量的数组) 维度)如果第一个的元素类型比特定的更具体 元素类型的第二个。
•否则如果一名成员未被解除 操作员和另一个是提升操作员,非提升操作员 更好。
•否则,两个功能成员都不会更好。
编辑:突出显示错误的部分。现在修好了。