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 (ocultación) y el intercambio de espacios de diseño en la clase derivada (anulación). La ocultación se controla marcando 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 como oculto 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 como ocultar por nombre y firma, entonces solo un miembro del mismo tipo con exactamente el mismo nombre y tipo (para campos) o firma de método (para métodos) se oculta de la clase derivada. La implementación de la distinción entre estas dos formas de ocultación la proporcionan en su totalidad los compiladores del lenguaje fuente y la biblioteca de reflexión; no tiene un impacto directo en el VES en sí.
(No queda 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 el VES lo ignora. 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 con el 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 se oculta Bar()
, porque el compilador de C # usa hidebysig
. Si usara la semántica "ocultar por nombre", no podría llamar Bar()
en absoluto a una referencia de tipo Derived
, aunque aún podría lanzarla a Base y llamarla de esa manera.
EDIT: He intentado esta compilando el código anterior para una DLL, ildasming, eliminando hidebysig
para Bar()
y Bar(string)
, ilasming de nuevo, a continuación, tratando de llamar Bar()
a 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).
Shadows
yOverloads
en VB.NET.Según la respuesta de THE SKEET, además, la razón de esto es que Java y C # permiten al cliente de una clase llamar a cualquier método con el mismo nombre, incluidos los de las clases base. Mientras que C ++ no: 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. Por lo tanto, 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
using
directiva, de modo que se conviertan en parte del "conjunto de sobrecargas" para ese nombre de método.fuente
Según Microsoft Docs
fuente