Partage via


OpCodes.Constrained Champ

Définition

Limite le type sur lequel un appel de méthode virtuelle est effectué.

public: static initonly System::Reflection::Emit::OpCode Constrained;
public static readonly System.Reflection.Emit.OpCode Constrained;
 staticval mutable Constrained : System.Reflection.Emit.OpCode
Public Shared ReadOnly Constrained As OpCode 

Valeur de champ

Remarques

Le tableau suivant répertorie le format d’assembly MSIL (Hexadécimal et MSIL) de l’instruction, ainsi qu’un bref résumé de référence :

Format Format d’assembly Description
FE 16 <T> contraint. thisType Appelez une méthode virtuelle sur un type contraint à être de type T.

Le préfixe constrained est autorisé uniquement sur une instruction de callvirt.

L’état de la pile MSIL à ce stade doit être le suivant :

  1. Un pointeur managé, ptr, est envoyé (push) sur la pile. Le type de ptr doit être un pointeur managé (&) vers thisType. Notez que cela diffère du cas d’une instruction callvirt non préfixée, qui attend une référence de thisType.

  2. Les arguments de méthode arg1 via argN sont envoyés (push) sur la pile, comme avec une instruction callvirt non préfixée.

Le préfixe constrained est conçu pour permettre à callvirt instructions d’être effectuées de manière uniforme, indépendamment de l'thisType est un type valeur ou un type référence.

Lorsqu’une instruction callvirtmethod a été préfixée par constrainedthisType, l’instruction est exécutée comme suit :

  • Si thisType est un type référence (par opposition à un type valeur), ptr est déréférencement et passé comme pointeur « this » au callvirt de method.

  • Si thisType est un type valeur et thisType implémente method, ptr est passée comme pointeur « this » à une instruction callmethod, pour l’implémentation de method par thisType.

  • Si thisType est un type valeur et que thisType n’implémente pas method, ptr est déréférencé, boxé et passé en tant que pointeur « this » à l’instruction callvirtmethod.

Ce dernier cas ne peut se produire que lorsque method a été défini sur Object, ValueTypeou Enum et non substitué par thisType. Dans ce cas, la boxe entraîne la création d’une copie de l’objet d’origine. Toutefois, étant donné qu’aucune des méthodes de Object, ValueTypeet Enum modifier l’état de l’objet, ce fait ne peut pas être détecté.

Le préfixe constrained prend en charge les générateurs IL qui créent du code générique. Normalement, l’instruction callvirt n’est pas valide sur les types valeur. Au lieu de cela, il est nécessaire que les compilateurs IL effectuent efficacement la transformation « this » décrite ci-dessus au moment de la compilation, en fonction du type de ptr et de la méthode appelée. Toutefois, lorsque ptr est un type générique inconnu au moment de la compilation, il n’est pas possible de rendre cette transformation au moment de la compilation.

L’opcode constrained permet aux compilateurs IL d’effectuer un appel à une fonction virtuelle de manière uniforme, indépendamment de l'ptr est un type valeur ou un type référence. Bien qu’il soit destiné au cas où thisType est une variable de type générique, le préfixe constrained fonctionne également pour les types non génériques et peut réduire la complexité de la génération d’appels virtuels dans des langages qui masquent la distinction entre les types valeur et les types de référence.

L’utilisation du préfixe constrained évite également les problèmes potentiels de contrôle de version avec les types valeur. Si le préfixe constrained n’est pas utilisé, différents il doivent être émis selon qu’un type valeur remplace ou non une méthode de System.Object. Par exemple, si un type valeur V remplace la méthode Object.ToString(), une instruction callV.ToString() est émise ; si ce n’est pas le cas, une instruction box et une instruction callvirtObject.ToString() sont émises. Un problème de contrôle de version peut survenir dans l’ancien cas si le remplacement est supprimé ultérieurement et, dans ce dernier cas, si un remplacement est ajouté ultérieurement.

Le préfixe constrained peut également être utilisé pour appeler des méthodes d’interface sur des types valeur, car la méthode de type valeur implémentant la méthode d’interface peut être modifiée à l’aide d’un MethodImpl. Si le préfixe constrained n’est pas utilisé, le compilateur est forcé de choisir les méthodes du type valeur à lier au moment de la compilation. L’utilisation du préfixe constrained permet à MSIL de se lier à la méthode qui implémente la méthode d’interface au moment de l’exécution, plutôt qu’au moment de la compilation.

La surcharge de méthode Emit suivante peut utiliser le constrained opcode :

S’applique à