我知道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
的重写中省略该关键字,则编译器会选择在两个方法中都装饰System.ParamArrayAttribute
。我当然用IL DASM验证了这些事情。
我的问题:
这是文档化的行为吗? 我已经彻底搜查了C#语言规范,没有找到任何提及此事的内容。
至少Visual Studio开发环境对此感到困惑。在上述方法调用中输入2,4,6
时,智能提示以提示方式显示void Okapi.Eat(params int[] leaves)
。
为了比较,我还尝试实现一个接口方法,并在接口和实现类中更改params
的存在/不存在,我还尝试定义一个委托类型,并更改委托类型定义或分配给我的委托类型变量的方法组中的params
。在这些情况下,更改params
是完全可行的。