Ответ 1
Из ECMA 335, раздел 8.10.4 раздела 1:
CTS обеспечивает независимый контроль над видимыми именами от базового типа (скрыть) и совместное использование слотов макета в класс (переопределение). Скрытие контролируется путем маркировки члена в производный класс как скрытый по имени или скрыть по имени и подписи. Прячется всегда выполняется на основе вида члена, т.е. производного поля имена могут скрывать имена базового поля, но не имена методов, имена свойств или имена событий. Если производный член отмечены скрыть по имени, затем члены тот же вид в базовом классе с одно и то же имя не отображается в производный класс; если элемент отмечен скрыть по имени и подписи, тогда только член того же типа с точно одно и то же имя и тип (для полей) или подпись метода (для методов) скрытый от производного класса. Выполнение различия между этими двумя формами предоставляемый полностью исходным языком компиляторы и библиотека отражения; он не оказывает прямого воздействия на VES сам по себе.
(Это не сразу очищается от этого, но 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()
, потому что компилятор С# использует hidebysig
. Если бы он использовал семантику "спрятать по имени", вы бы вообще не смогли вызвать Bar()
на ссылку типа Derived
, хотя вы все равно могли бы передать ее в базу и вызвать ее таким образом.
EDIT: Я только что попробовал это, скомпилировав вышеуказанный код в 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();
(Нет проблем с компиляцией.)