93 votes

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

En utilisant ildasm et un programme c#, par exemple

donne :

Que fait la construction hidebysig ?

158voto

Jon Skeet Points 692016

À partir de l'ECMA 335, section 8.10.4 de la partition 1:

La CTS fournit un contrôle indépendant sur les deux noms qui sont visibles à partir d'un type de base (caché) et le le partage de la disposition des fentes dans la dérivée catégorie (primordial). Le masquage est contrôlé par le marquage d'un membre de la dérivée de la classe que ce soit par son nom masquer ou se cache le nom et la signature. Cacher est toujours effectuée sur la base de la nature de membre, qui est dérivée de terrain les noms peuvent cacher de la base de noms de champ, mais pas de méthode de noms, les noms de propriété, ou les noms d'événements. Si un membre dérivé est marqué cacher par nom, ensuite, les membres de le même genre dans la classe de base avec le même nom ne sont pas visibles dans l' dérivée de la classe; si le membre est marqué cacher sous le nom de andsignature alors qu'un membre du même genre avec exactement le même nom et le type (pour les champs) ou signature de la méthode (pour les méthodes) est caché de la classe dérivée. La mise en œuvre de la distinction entre ces deux formes de masquage est entièrement de langue source les compilateurs et la réflexion de la bibliothèque; il n'a pas d'impact direct sur la VES lui-même.

(C'est pas clair tout de suite, mais hidebysig signifie "cacher par nom et signature".)

Également dans la section 15.4.2.2 de la partition 2:

hidebysig est fourni pour l'utilisation de outils et est ignoré par le VES. Il spécifie que la méthode déclarée masque toutes les méthodes de la classe de base des types qui ont une méthode d'appariement signature; s'il est omis, la méthode doivent masquer toutes les méthodes de la même nom, indépendamment de la signature.

Par exemple, supposons que vous avez:

public class Base
{
    public void Bar()
    {
    }
}

public class Derived : Base
{
    public void Bar(string x)
    {
    }
}

...

Derived d = new Derived();
d.Bar();

C'est valable, car Bar(string) ne pas masquer Bar(), car le compilateur C# utilise hidebysig. Si elle a utilisé "se cache le nom de" la sémantique, vous ne seriez pas en mesure d'appeler Bar() sur une référence de type Derived, bien que vous pouvez toujours jeter à la Base et de l'appeler de cette façon.

EDIT: j'ai juste essayé en compilant le code d'une DLL, ildasming, la suppression d' hidebysig pour Bar() et Bar(string), ilasming à nouveau, puis d'essayer de les appeler Bar() de code:

Derived d = new Derived();
d.Bar();

Test.cs(6,9): error CS1501: No overload for method 'Bar' takes '0' arguments

Cependant:

Base d = new Derived();
d.Bar();

(Pas de problèmes de compilation.)

15voto

Daniel Earwicker Points 63298

Comme par LE SKEET réponse, en outre, la raison pour cela est que Java et C# de permettre au client d'une classe d'appeler les méthodes avec le même nom, y compris ceux des classes de base. Alors que C++ ne prend pas: si la classe dérivée définit même une seule méthode avec le même nom qu'une méthode dans la classe de base, alors le client ne peut pas appeler directement la méthode de classe de base, même si elle ne prend pas les mêmes arguments. Si la fonction a été inclus dans CIL à l'appui de ces deux approches à la surcharge.

En C++, vous pouvez effectivement importer un ensemble nommé de surcharges de la classe de base avec un using la directive, de sorte qu'ils deviennent une partie de la "surcharge set" pour que le nom de la méthode.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X