Quel est le but de hidebysig dans une méthode MSIL?

En utilisant ildasm et un programme C # par exemple

static void Main(ssortingng[] args) { } 

donne:

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

Que fait la construction hidebysig?

De l’ ECMA 335 , section 8.10.4 de la partition 1:

Le CTS fournit un contrôle indépendant à la fois sur les noms visibles depuis un type de base (masquage) et sur le partage des logements de présentation dans la classe dérivée (en remplacement). Le masquage est contrôlé en marquant un membre dans la classe dérivée comme masqué par 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éthodes, les noms de propriété ou les noms d’événements. Si un membre dérivé est marqué par son nom, les membres du même type 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é masquer par nom-et-signature, alors seul un membre du même type avec exactement le même nom et le même type (pour les champs) ou la même méthode (pour les méthodes) est masqué dans la classe dérivée. La mise en œuvre de la distinction entre ces deux formes de dissimulation est entièrement assurée par les compilateurs en langage source et la bibliothèque de reflection; cela n’a pas d’impact direct sur le VES lui-même.

(Ce n’est pas immédiatement clair, mais hidebysig signifie “cacher par nom et signature”.)

Également à la section 15.4.2.2 de la partition 2:

hidebysig est fourni pour l’utilisation des 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 classes 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.

Par exemple, supposons que vous ayez:

 public class Base { public void Bar() { } } public class Derived : Base { public void Bar(ssortingng x) { } } ... Derived d = new Derived(); d.Bar(); 

C’est valide, car Bar(ssortingng) ne masque pas Bar() , car le compilateur C # utilise hidebysig . Si elle utilisait la sémantique “cacher par son nom”, vous ne pourriez pas appeler Bar() sur une référence de type Derived , bien que vous puissiez toujours la convertir en Base et l’appeler de cette manière.

EDIT: Je viens d’essayer cela en compilant le code ci-dessus dans une DLL, en le supprimant, en supprimant hidebysig pour Bar() et Bar(ssortingng) , en le réinsérant, puis en essayant d’appeler Bar() depuis 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(); 

(Pas de problèmes de compilation.)

Selon la réponse de THE SKEET, la raison en est que Java et C # permettent au client d’une classe d’appeler toutes les méthodes du 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 même une seule méthode portant le même nom qu’une méthode dans la classe de base, 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 en matière de surcharge.

En C ++, vous pouvez importer un ensemble de surcharges nommé à partir de la classe de base avec une directive using , de sorte qu’elles deviennent partie intégrante de “l’ensemble de surcharge” pour ce nom de méthode.

Selon Microsoft Docs

Lorsqu’un membre d’une classe dérivée est déclaré avec le modificateur C # new ou le modificateur Visual Basic Shadows , il peut masquer un membre du même nom dans la classe de base. C # cache les membres de la classe de base par signature. En d’autres termes, si le membre de la classe de base a plusieurs surcharges, le seul qui est masqué est celui qui a la même signature. En revanche, Visual Basic masque toutes les surcharges de classe de base. Ainsi, IsHideBySig renvoie false sur un membre déclaré avec le modificateur Visual Basic Shadows et true sur un membre déclaré avec le modificateur C # new .