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