С ECMA 335 , раздел 8.10.4 раздела 1:
CTS обеспечивает независимый контроль
над обоими именами, которые видны
от базового типа (скрытие) и тому
совместное использование слотов макета в производном
класс (переопределение). Скрывается
контролируется путем маркировки члена в
производный класс как либо скрыть по имени
или скрыть по имени и подписи. Прячется
всегда выполняется в зависимости от вида
члена, то есть производного поля
Имена могут скрывать базовые имена полей, но
не имена методов, имена свойств или
имена событий. Если производный член
помечены как скрытые по имени, затем члены
тот же вид в базовом классе с
одно и то же имя не видно в
производный класс; если участник отмечен
скрыть по имени и подписи, то только
член того же рода с точно
то же имя и тип (для полей) или
сигнатура метода (для методов)
скрыто от производного класса.
Осуществление различия
между этими двумя формами сокрытия
обеспечивается исключительно исходным языком
компиляторы и библиотека отражений;
это не имеет прямого влияния на ВЭС
сам по себе.
(Из этого не сразу понятно, но hidebysig
означает «скрыть по имени и подписи».)
Также в разделе 15.4.2.2 раздела 2:
hidebysig поставляется для использования
инструменты и игнорируется VES. Это
указывает, что заявленный метод
скрывает все методы базового класса
типы с подходящим методом
подпись; если не указано, метод
следует скрыть все методы одинаково
имя, независимо от подписи.
В качестве примера предположим, что у вас есть:
public class Base
{
public void Bar()
{
}
}
public class Derived : Base
{
public void Bar(string x)
{
}
}
...
Derived d = new Derived();
d.Bar();
Это верно, потому что Bar(string)
не скрыть Bar()
, потому что компилятор C # использует hidebysig
. Если бы он использовал семантику «скрыть по имени», вы бы вообще не смогли вызвать Bar()
для ссылки типа Derived
, хотя вы все равно могли бы привести его к Base и вызвать его таким образом.
РЕДАКТИРОВАТЬ: Я только что попробовал это, скомпилировав код выше в DLL, ildasming его, удалив hidebysig
для Bar()
и Bar(string)
, снова коснувшись его, затем пытаясь вызвать Bar()
из другого кода :
Derived d = new Derived();
d.Bar();
Test.cs(6,9): error CS1501: No overload for method 'Bar' takes '0' arguments
Тем не менее:
Base d = new Derived();
d.Bar();
(проблем с компиляцией нет.)