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'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 :
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 etstelem
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 doncreadonly
d’un no-op dans ce cas.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 lesldfld
instructions ,ldflda
,stfld
,call
ouconstrained callvirt
.pointer
En tant que paramètre de l’instructionldobj
ou de l’uneldind
des instructions.source
En tant que paramètre de l’instructioncpobj
.
Toutes les autres opérations non autorisées, y compris les stobj
opérations , initobj
ou 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
: