Я знаю, что модификатор 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.
Мой вопрос:
Является ли это документированным поведением? Я тщательно изучил спецификацию языка С#, не найдя упоминания об этом.
Я могу сказать, что по крайней мере среда разработки Visual Studio запуталась в этом. При вводе 2, 4, 6
в вызове метода выше intellisense показывает мне void Okapi.Eat(params int[] leaves)
в подсказке.
Для сравнения я также попытался реализовать метод интерфейса и изменить присутствие/отсутствие params
в интерфейсе и классе реализации, и я попытался определить тип делегата и изменить params
или нет в определении типа делегата или метод, группа методов которого я назначен переменной моего типа делегата. В этих случаях было вполне возможно изменить params
-ness.