我知道params
修饰符(将数组类型的一个参数转换为所谓的“参数数组”)特别不是方法签名的一部分。现在考虑这个例子:
class Giraffid
{
public virtual void Eat(int[] leaves)
{
Console.WriteLine("G");
}
}
class Okapi : Giraffid
{
public override void Eat(params int[] leaves)
{
Console.WriteLine("O");
}
}
这编译没有警告。然后说:
var okapi = new Okapi();
okapi.Eat(2, 4, 6); // will not compile!
给出一个错误(No overload for method 'Eat' takes 3 arguments
)。
现在,我知道编译器会将params
修饰符转换为System.ParamArrayAttribute
相关参数的应用程序。通常,将一个属性集合应用于虚拟方法的参数,然后在派生类的覆盖方法中用不同的属性集修饰“对应”参数是没有问题的。
然而编译器选择params
默默地忽略我的关键字。相反,如果反过来,将其应用于params
基类中的参数Giraffid
,然后在覆盖中省略关键字,则Okapi
编译器会选择用. 当然,我用 IL DASM 验证了这些东西。System.ParamArrayAttribute
我的问题:
这是记录在案的行为吗?我已经彻底搜索了 C# 语言规范,但没有发现任何提及这一点。
我可以说至少 Visual Studio 开发环境对此感到困惑。2, 4, 6
在上述方法调用中键入时,智能感知会在提示中显示void Okapi.Eat(params int[] leaves)
我。
params
为了比较,我还尝试实现一个接口方法并更改接口和实现类中的存在/不存在,我尝试定义一个委托类型并params
在委托类型定义或我分配给其方法组的方法中更改或不更改我的委托类型的变量。在这些情况下,完全有可能改变params
-ness。