cil - name - ¿Cuál es el propósito de hidebysig en un método MSIL?
meta tags generator (2)
De ECMA 335 , sección 8.10.4 de la partición 1:
El CTS proporciona control independiente sobre los nombres que son visibles desde un tipo base (oculto) y el intercambio de ranuras de diseño en la clase derivada (anulación). La ocultación se controla marcando a un miembro en la clase derivada como ocultar por nombre u ocultar por nombre y firma. La ocultación siempre se realiza en función del tipo de miembro, es decir, los nombres de campo derivados pueden ocultar nombres de campos base, pero no nombres de métodos, nombres de propiedades o nombres de eventos. Si un miembro derivado está marcado ocultar por nombre, los miembros del mismo tipo en la clase base con el mismo nombre no son visibles en la clase derivada; si el miembro está marcado hide por nombre y firma, solo un miembro del mismo tipo con exactamente el mismo nombre y tipo (para los campos) o la firma del método (para los métodos) está oculto de la clase derivada. La implementación de la distinción entre estas dos formas de ocultación se proporciona en su totalidad por los compiladores del lenguaje fuente y la biblioteca de reflexión; no tiene un impacto directo en el VES mismo.
(No está claro de inmediato, pero hidebysig
significa "ocultar por nombre y firma").
También en la sección 15.4.2.2 de la partición 2:
hidebysig se suministra para el uso de herramientas y es ignorado por el VES. Especifica que el método declarado oculta todos los métodos de los tipos de clase base que tienen una firma de método coincidente; cuando se omite, el método debe ocultar todos los métodos del mismo nombre, independientemente de la firma.
Como ejemplo, suponga que tiene:
public class Base
{
public void Bar()
{
}
}
public class Derived : Base
{
public void Bar(string x)
{
}
}
...
Derived d = new Derived();
d.Bar();
Eso es válido, porque Bar(string)
no oculta Bar()
, porque el compilador de C # usa hidebysig
. Si usaba la semántica de "ocultar por nombre", no podría llamar a Bar()
en absoluto en una referencia de tipo Derived
, aunque aún podría lanzarlo a Base y llamarlo de esa manera.
EDITAR: He intentado esto compilando el código anterior en una DLL, ildasming it, eliminando hidebysig
para Bar()
y Bar(string)
, volviéndolo a poner, y luego tratando de llamar a Bar()
desde otro código:
Derived d = new Derived();
d.Bar();
Test.cs(6,9): error CS1501: No overload for method ''Bar'' takes ''0'' arguments
Sin embargo:
Base d = new Derived();
d.Bar();
(Sin problemas de compilación)
Usando ildasm y un programa C # ej.
static void Main(string[] args)
{
}
da:
.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
¿Qué hace la construcción hidebysig?
Según la respuesta de THE SKEET, además, la razón para esto es que Java y C # permiten que el cliente de una clase llame a cualquier método con el mismo nombre, incluidos los de las clases base. Mientras que C ++ no lo hace: si la clase derivada define incluso un solo método con el mismo nombre que un método en la clase base, entonces el cliente no puede llamar directamente al método de la clase base, incluso si no toma los mismos argumentos. Entonces, la función se incluyó en CIL para admitir ambos enfoques de sobrecarga.
En C ++, puede importar efectivamente un conjunto de sobrecargas con nombre de la clase base con una directiva using
, para que forme parte del "conjunto de sobrecarga" para ese nombre de método.