OpCodes.Readonly Campo

Definizione

Specifica che l'operazione di indirizzo di matrice successiva non esegue alcun controllo dei tipi in fase di esecuzione e che restituisce un puntatore gestito la cui mutabilità è limitata.

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 

Valore del campo

Commenti

La tabella seguente elenca il formato di assembly MSIL (Intermediate Language) esadecimale e Microsoft istruzione, insieme a un breve riepilogo di riferimento:

Formato Formato assembly Description
FE 1E readonly. Specificare che l'operazione di indirizzo di matrice successiva non esegue alcun controllo dei tipi in fase di esecuzione e che restituisce un puntatore gestito con mutabilità limitata.

Questo prefisso può essere visualizzato immediatamente prima dell'istruzione ldelema e le chiamate al metodo speciale Address sulle matrici. L'effetto sull'operazione successiva è duplicato:

  1. In fase di esecuzione non viene eseguita alcuna operazione di controllo del tipo. Si noti che in genere è presente un controllo implicito dei tipi per le ldelema istruzioni e stelem quando vengono usate nelle matrici di tipi di riferimento. Non esiste mai un controllo del tipo di runtime per le classi valore, quindi readonly è un no-op in tal caso.

  2. Il verificatore considera il risultato dell'operazione address-of come puntatore gestito con mutabilità limitata.

Il puntatore ha una mutabilità limitata perché il tipo che definisce controlla se il valore può essere modificato. Per le classi valore che non espongono campi o metodi pubblici che aggiornano il valore sul posto, il puntatore è di sola lettura (di conseguenza il nome del prefisso). In particolare, le classi che rappresentano tipi primitivi (ad esempio, System.Int32) non espongono modificatori e pertanto sono di sola lettura.

Un puntatore gestito limitato in questo modo può essere usato solo nei modi seguenti:

  • object Come parametro per le ldfldistruzioni , ldfldastfld, call, oconstrained callvirt .

  • pointer Come parametro per l'istruzione ldobj o per una delle ldind istruzioni.

  • source Come parametro per l'istruzionecpobj.

Tutte le altre operazioni non consentite, incluse le stobjoperazioni , initobjo mkrefany o una qualsiasi delle stind istruzioni.

Lo scopo del prefisso è evitare un controllo del tipo durante il readonly recupero di un elemento da una matrice nel codice generico. Ad esempio, l'espressione arr[i].m(), dove il tipo di elemento della matrice arr è un tipo generico vincolato ad avere un'interfaccia con il metodo m, potrebbe essere compilato nel codice MSIL seguente.

ldloc arr
ldloc i
readonly.
ldelema !0    // Loads the pointer to the object.
…             // Load the arguments to the call.
constrained. !0
callvirt m

Senza il readonly prefisso, l'istruzione ldelema eseguirà un controllo del tipo nel caso in cui !0 fosse un tipo riferimento. Non solo questo controllo di tipo è inefficiente, ma è semanticamente errato. Il controllo del tipo è ldelema una corrispondenza esatta, che è troppo forte. Se la matrice contiene sottoclassi di tipo !0, il codice precedente non riuscirà a controllare il tipo.

L'indirizzo dell'elemento della matrice viene recuperato, anziché l'elemento stesso, per avere un handle per che funziona sia per arr[i] i tipi valore che per i tipi riferimento e quindi può essere passato all'istruzione constrained callvirt .

In generale, non sarebbe sicuro ignorare il controllo di runtime se la matrice contiene elementi di un tipo riferimento. Per essere sicuri, è necessario assicurarsi che non vengano apportate modifiche alla matrice tramite questo puntatore. Le regole di verifica assicurano questo problema. Il puntatore gestito con restrizioni può essere passato come oggetto di chiamate al metodo di istanza, pertanto non è strettamente di sola lettura per i tipi valore, ma non esiste alcun problema di sicurezza dei tipi di tipo per i tipi valore.

L'overload del metodo seguente Emit può usare il readonly codice operativo:

Si applica a