Вопрос

Используя 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?

Это было полезно?

Решение

От ECMA 335, раздел 8.10.4 раздела 1:

CTS обеспечивает независимый контроль как над именами, которые видны из базового типа (скрытие), так и над совместным использованием слотов компоновки в производном классе (переопределение).Скрытие контролируется путем пометки элемента в производном классе как либо скрываемый по имени , либо скрываемый по имени и подписи.Скрытие всегда выполняется на основе типа элемента, то есть производного поля имена могут скрывать имена базовых полей, но не имена методов, имена свойств или имена событий.Если производный элемент помечен как скрыть по имени, то члены того же типа в базовом классе с тем же именем не отображаются в производном классе;если элемент обозначен скрыть имя и подпись, то только член же с точностью то же имя и тип (для поля) или подпись метода (методов) является скрыт от производного класса.Реализация различия между этими двумя формами скрытия полностью обеспечивается исходным языком компиляторы и библиотека отражения;это не оказывает прямого влияния на саму VES .

(Из этого не сразу понятно, но hidebysig означает "скрывать по имени и подписи".)

Также в разделе 15.4.2.2 раздела 2:

hidebysig поставляется для использования tools и игнорируется 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, обновив его, удалив 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();

(Никаких проблем с компиляцией.)

Другие советы

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

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

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

Когда член в производном классе объявляется с помощью C# new модификатор или Visual Basic Shadows модификатор, он может скрывать элемент с тем же именем в базовом классе.C # скрывает члены базового класса с помощью подписи.Это то есть, если элемент базового класса имеет несколько перегрузок, единственная, которая скрыта, - это та, которая имеет идентичную сигнатуру.В отличие от этого, Visual Basic скрывает все перегрузки базового класса.Таким образом, Ишидебысиг ВОЗВРАТ false на элементе, объявленном с помощью Visual Basic Shadows модификатор, и true на члене, объявленном с помощью C# new модификатор.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top