Какова цель hidebysig в ​​методе MSIL? - PullRequest
85 голосов
/ 18 марта 2009

Использование ildasm и программы на C #, например

static void Main(string[] args)
{

}

дает:

.method private hidebysig static void  Main(string[] args) cil managed
{
  .entrypoint
  // Code size       2 (0x2)
  .maxstack  8
  IL_0000:  nop
  IL_0001:  ret
} // end of method Program::Main

Что делает конструкция hidebysig?

Ответы [ 3 ]

148 голосов
/ 18 марта 2009

С 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();

(проблем с компиляцией нет.)

14 голосов
/ 18 марта 2009

Согласно ответу SKEET, кроме того, причина в том, что Java и C # позволяют клиенту класса вызывать любые методы с одинаковыми именами, в том числе из базовых классов. В то время как C ++ этого не делает: если производный класс определяет даже один метод с тем же именем, что и метод в базовом классе, то клиент не может напрямую вызывать метод базового класса, даже если он не принимает те же аргументы. Поэтому функция была включена в CIL для поддержки обоих подходов к перегрузке.

В C ++ вы можете эффективно импортировать один именованный набор перегрузок из базового класса с помощью директивы using, чтобы они стали частью «набора перегрузок» для этого имени метода.

0 голосов
/ 27 марта 2018

Согласно Документам Microsoft

Когда член в производном классе объявлен с модификатором C # new или модификатор Visual Basic Shadows, он может скрывать один и тот же член имя в базовом классе. C # скрывает членов базового класса по подписи. Тот если член базового класса имеет несколько перегрузок, единственный, который скрыт тот, который имеет идентичную подпись. В отличие от Visual Basic скрывает все перегрузки базового класса. Таким образом, IsHideBySig возвращает false для члена, объявленного с помощью Visual Basic Shadows и true для члена, объявленного с модификатором C # new.

...