OpCodes.Readonly Champ
Définition
Important
Certaines informations portent sur la préversion du produit qui est susceptible d’être en grande partie modifiée avant sa publication. Microsoft exclut toute garantie, expresse ou implicite, concernant les informations fournies ici.
Spécifie que l’opération d’adresse de tableau suivante n’effectue aucune vérification de type au moment de l’exécution et qu’elle retourne un pointeur managé dont la mutabilité est restreinte.
public: static initonly System::Reflection::Emit::OpCode Readonly;
public static readonly System.Reflection.Emit.OpCode Readonly;
staticval mutable Readonly : System.Reflection.Emit.OpCode
Public Shared ReadOnly Readonly As OpCode
Valeur de champ
Remarques
Le tableau suivant répertorie le format d'assembly hexadécimal et Microsoft (MSIL) de l'instruction, ainsi qu'un bref résumé de référence :
| Format | Format d’assembly | Description |
|---|---|---|
| FE 1E | readonly. | Spécifiez que l’opération d’adresse de tableau suivante n’effectue aucune vérification de type au moment de l’exécution et qu’elle retourne un pointeur managé avec une mutabilité restreinte. |
Ce préfixe ne peut apparaître que immédiatement avant l’instruction ldelema et les appels à la méthode spéciale Address sur les tableaux. Son effet sur l’opération suivante est double :
Au moment de l’exécution, aucune opération de vérification de type n’est effectuée. Notez qu’il existe normalement une vérification de type implicite pour les instructions et
stelemlesldelemainstructions utilisées sur les tableaux de types de référence. Il n’existe jamais de vérification de type d’exécution pour les classes de valeur. Il s’agit doncreadonlyd’une no-op dans ce cas.Le vérificateur traite le résultat de l’opération d’adresse en tant que pointeur managé avec une mutabilité restreinte.
Le pointeur est dit avoir une mutabilité restreinte, car le type de définition contrôle si la valeur peut être mutée. Pour les classes de valeur qui n’exposent aucun champ public ou méthode qui mettent à jour la valeur en place, le pointeur est en lecture seule (par conséquent, le nom du préfixe). En particulier, les classes représentant des types primitifs (par exemple, System.Int32) n’exposent pas de mutateurs et sont donc en lecture seule.
Un pointeur managé restreint de cette manière ne peut être utilisé que de la manière suivante :
objectEn tant que paramètre pour lesldfldinstructions , ,callldfldastfldou .constrained callvirtpointerEn tant que paramètre de l’instructionldobjou de l’uneldinddes instructions.sourceEn tant que paramètre de l’instructioncpobj.
Toutes les autres opérations non autorisées, y compris les opérations, initobjou mkrefany les stobjopérations, ou l’une des stind instructions.
L’objectif du préfixe est d’éviter une vérification de type lors de l’extraction readonly d’un élément à partir d’un tableau dans le code générique. Par exemple, l’expression arr[i].m(), où le type d’élément du tableau arr est un type générique qui a été contraint d’avoir une interface avec la méthode m, peut être compilé sur le MSIL suivant.
ldloc arr
ldloc i
readonly.
ldelema !0 // Loads the pointer to the object.
… // Load the arguments to the call.
constrained. !0
callvirt m
Sans le readonly préfixe, l’instruction ldelema effectuerait une vérification de type dans le cas où !0 était un type référence. Non seulement ce contrôle de type est inefficace, mais il est sémantiquement incorrect. La vérification ldelema de type est une correspondance exacte, qui est trop forte. Si le tableau contenait des sous-classes de type !0, le code ci-dessus échouerait à la vérification du type.
L’adresse de l’élément de tableau est extraite, au lieu de l’élément lui-même, afin d’avoir un handle pour cela fonctionne pour arr[i] les types valeur et les types de référence, et peut donc être passé à l’instruction constrained callvirt .
En général, il serait dangereux d’ignorer la vérification au moment de l’exécution si le tableau contenait des éléments d’un type référence. Pour être sûr, il est nécessaire de s’assurer qu’aucune modification du tableau n’est apportée par le biais de ce pointeur. Les règles du vérificateur garantissent cela. Le pointeur managé restreint peut être passé en tant qu’objet d’appels de méthode d’instance. Il n’est donc pas strictement en lecture seule pour les types valeur, mais il n’existe aucun problème de sécurité de type pour les types valeur.
La surcharge de méthode suivante Emit peut utiliser l’opcode readonly :