OpCodes.Readonly Champ

Définition

Spécifie que l'opération d'adresse de tableau suivante n'exécute aucun contrôle de type au moment de l'exécution et qu'il 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 MSIL et hexadécimal de l’instruction, ainsi qu’un bref résumé des références :

Format Format d’assembly Description
FE 1E readonly. Spécifiez que l’opération d’adresse de tableau suivante n’exécute aucun type case activée au moment de l’exécution et qu’elle retourne un pointeur managé avec une mutabilité restreinte.

Ce préfixe ne peut apparaître qu’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 :

  1. Au moment de l’exécution, aucune opération de type case activée n’est effectuée. Notez qu’il existe normalement un type implicite case activée pour les ldelema instructions et stelem lorsqu’elles sont utilisées sur des tableaux de types de référence. Il n’y a jamais de type d’exécution case activée pour les classes de valeur. Il s’agit donc readonly d’un no-op dans ce cas.

  2. Le vérificateur traite le résultat de l’opération d’adresse comme un pointeur managé avec une mutabilité restreinte.

La mutabilité du pointeur est limitée, 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 aucune méthode qui met à jour la valeur en place, le pointeur est en lecture seule (d’où 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 façon ne peut être utilisé que de la manière suivante :

  • object En tant que paramètre pour les ldfldinstructions , ldflda, stfld, callouconstrained callvirt .

  • pointer En tant que paramètre de l’instruction ldobj ou de l’une ldind des instructions.

  • source En tant que paramètre de l’instructioncpobj.

Toutes les autres opérations non autorisées, y compris les stobjopérations , initobjou mkrefany , ou ou l’une des stind instructions.

L’objectif du readonly préfixe est d’éviter un type case activée lors de l’extraction d’un élément à partir d’un tableau dans du 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ée dans 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 exécuterait un type case activée dans le cas où !0 était un type référence. Non seulement ce type case activée inefficace, mais il est sémantiquement incorrect. Le type case activée pour ldelema est une correspondance exacte, qui est trop forte. Si le tableau contenait des sous-classes de type !0, le code ci-dessus échouerait le type case activée.

L’adresse de l’élément tableau est extraite, au lieu de l’élément lui-même, afin d’avoir un handle pour arr[i] qui fonctionne à la fois pour les types de valeurs 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 le case activée d’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 via 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 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 :

S’applique à