D'après ECMA 335 , section 8.10.4 de la partition 1:
Le CTS fournit un contrôle indépendant à la fois sur les noms visibles à partir d'un type de base (masquage) et sur le partage des emplacements de disposition dans la classe dérivée (substitution). Le masquage est contrôlé en marquant un membre de la classe dérivée comme masqué par son nom ou masqué par nom et signature. Le masquage est toujours effectué en fonction du type de membre, c'est-à-dire que les noms de champs dérivés peuvent masquer les noms de champs de base, mais pas les noms de méthode, les noms de propriété ou les noms d'événement. Si un membre dérivé est marqué par son nom, les membres du même genre dans la classe de base portant le même nom ne sont pas visibles dans la classe dérivée; si le membre est marqué hide par nom et signature, alors seul un membre du même type avec exactement le même nom et type (pour les champs) ou la signature de méthode (pour les méthodes) est masqué de la classe dérivée. La mise en œuvre de la distinction entre ces deux formes de masquage est entièrement assurée par les compilateurs en langage source et la bibliothèque de réflexion; il n'a pas d'impact direct sur le VES lui-même.
(Ce n'est pas immédiatement clair à partir de cela, mais hidebysig
signifie "masquer par nom et signature".)
Également dans la section 15.4.2.2 de la partition 2:
hidebysig est fourni pour l'utilisation d'outils et est ignoré par le VES. Il spécifie que la méthode déclarée masque toutes les méthodes des types de classe de base qui ont une signature de méthode correspondante; lorsqu'elle est omise, la méthode doit masquer toutes les méthodes du même nom, quelle que soit la signature.
À titre d'exemple, supposons que vous ayez:
public class Base
{
public void Bar()
{
}
}
public class Derived : Base
{
public void Bar(string x)
{
}
}
...
Derived d = new Derived();
d.Bar();
C'est valide, car Bar(string)
ne se cache pasBar()
, car le compilateur C # utilise hidebysig
. S'il utilisait la sémantique "hide by name", vous ne pourriez pas du tout appeler Bar()
une référence de type Derived
, bien que vous puissiez toujours la convertir en Base et l'appeler de cette façon.
EDIT: Je viens d'essayer cela en compilant le code ci-dessus dans une DLL, en l'ildasming, en le supprimant hidebysig
pour Bar()
et Bar(string)
, en le réenregistrant, puis en essayant d'appeler à Bar()
partir d'un autre code:
Derived d = new Derived();
d.Bar();
Test.cs(6,9): error CS1501: No overload for method 'Bar' takes '0' arguments
Toutefois:
Base d = new Derived();
d.Bar();
(Aucun problème de compilation.)
Shadows
etOverloads
dans VB.NET.Selon la réponse de THE SKEET, en outre, la raison en est que Java et C # permettent au client d'une classe d'appeler toutes les méthodes portant le même nom, y compris celles des classes de base. Alors que C ++ ne le fait pas: si la classe dérivée définit ne serait-ce qu'une seule méthode avec le même nom qu'une méthode de la classe de base, alors le client ne peut pas appeler directement la méthode de la classe de base, même si elle ne prend pas les mêmes arguments. La fonctionnalité a donc été incluse dans CIL pour prendre en charge les deux approches de la surcharge.
En C ++, vous pouvez effectivement importer un ensemble nommé de surcharges à partir de la classe de base avec une
using
directive, afin qu'elles deviennent partie intégrante du «jeu de surcharges» pour ce nom de méthode.la source
Selon Microsoft Docs
la source