OpCodes.Constrained Campo

Definizione

Vincola il tipo su cui viene eseguita una chiamata al metodo virtuale.

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 

Valore del campo

Commenti

La tabella seguente elenca il formato di assembly MSIL (Hexadecimal e Microsoft Intermediate Language) dell'istruzione, insieme a un breve riepilogo dei riferimenti:

Formato Formato assembly Descrizione
FE 16 <T> Vincolata. thisType Chiamare un metodo virtuale su un tipo vincolato per essere di tipo T.

Il constrained prefisso è consentito solo su un'istruzione callvirt .

Lo stato dello stack MSIL a questo punto deve essere il seguente:

  1. Un puntatore gestito, ptr, viene inserito nello stack. Il tipo di ptr deve essere un puntatore gestito (&) a thisType. Si noti che questo comportamento è diverso dal caso di un'istruzione senza prefisso callvirt , che prevede un riferimento di thisType.

  2. Gli argomenti del metodo tramite argN vengono inseriti arg1 nello stack, esattamente come con un'istruzione senza callvirt prefisso.

Il constrained prefisso è progettato per consentire callvirt l'uso uniforme delle istruzioni indipendentemente dal fatto che thisType si tratti di un tipo valore o di un tipo riferimento.

Quando un'istruzione callvirtmethod è preceduta da constrainedthisType, l'istruzione viene eseguita come segue:

  • Se thisType è un tipo riferimento (anziché un tipo valore), ptr viene dereferenziato e passato come puntatore "this" a callvirt di method.

  • Se thisType è un tipo di valore e thisType implementamethod, ptr viene passato unmodified come puntatore "this" a un'istruzionecallmethod, per l'implementazione di method da .thisType

  • Se thisType è un tipo di valore e thisType non implementa method , ptr viene dereferenziato, sottoposto a boxing e passato come puntatore "this" all'istruzione callvirtmethod .

Questo ultimo caso può verificarsi solo quando method è stato definito in Object, ValueTypeo Enum e non è sottoposto a override da thisType. In questo caso, il boxing determina la creazione di una copia dell'oggetto originale. Tuttavia, poiché nessuno dei metodi di Object, ValueTypee Enum modifica lo stato dell'oggetto , non può essere rilevato.

Il constrained prefisso supporta i generatori IL che creano codice generico. In genere l'istruzione callvirt non è valida per i tipi valore. È invece necessario che i compilatori IL eseguano in modo efficace la trasformazione "this" descritta in precedenza in fase di compilazione, a seconda del tipo di ptr e del metodo chiamato. Tuttavia, quando ptr è un tipo generico sconosciuto in fase di compilazione, non è possibile eseguire questa trasformazione in fase di compilazione.

Il constrained codice operativo consente ai compilatori IL di effettuare una chiamata a una funzione virtuale in modo uniforme indipendentemente dal fatto che ptr sia un tipo valore o un tipo riferimento. Anche se è destinato al caso in cui thisType è una variabile di tipo generico, il constrained prefisso funziona anche per i tipi non generici e può ridurre la complessità della generazione di chiamate virtuali in linguaggi che nascondono la distinzione tra tipi valore e tipi di riferimento.

L'uso del constrained prefisso evita anche potenziali problemi di controllo delle versioni con i tipi valore. Se il constrained prefisso non viene utilizzato, è necessario generare un'istruzione IL diversa a seconda che un tipo di valore eseva o meno l'override di un metodo di System.Object. Ad esempio, se un tipo valore V esegue l'override del metodo Object.ToString(), viene generata un'istruzione callV.ToString() . In caso contrario, vengono generate un'istruzione box e un'istruzione callvirtObject.ToString() . Un problema di controllo delle versioni può verificarsi nel primo caso se l'override viene successivamente rimosso e nel secondo caso se viene aggiunto un override in un secondo momento.

Il constrained prefisso può essere usato anche per la chiamata di metodi di interfaccia sui tipi valore, perché il metodo di tipo valore che implementa il metodo di interfaccia può essere modificato usando un oggetto MethodImpl. Se il constrained prefisso non viene usato, il compilatore deve scegliere a quale dei metodi del tipo valore associare in fase di compilazione. L'uso del constrained prefisso consente all'MSIL di eseguire l'associazione al metodo che implementa il metodo di interfaccia in fase di esecuzione, anziché in fase di compilazione.

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

Si applica a