OpCodes.Constrained Campo
Definizione
Importante
Alcune informazioni sono relative alla release non definitiva del prodotto, che potrebbe subire modifiche significative prima della release definitiva. Microsoft non riconosce alcuna garanzia, espressa o implicita, in merito alle informazioni qui fornite.
Vincola il tipo su cui viene effettuata 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 (Esadecimale e MSIL) dell'istruzione, insieme a un breve riepilogo di riferimento:
Formato | Formato assembly | Descrizione |
---|---|---|
FE 16 <T > |
obbligato. thisType |
Chiamare un metodo virtuale su un tipo vincolato per essere di tipo T . |
Il prefisso constrained
è consentito solo in un'istruzione callvirt
.
Lo stato dello stack MSIL a questo punto deve essere il seguente:
Un puntatore gestito,
ptr
, viene inserito nello stack. Il tipo diptr
deve essere un puntatore gestito (&
) perthisType
. Si noti che questo comportamento è diverso dal caso di un'istruzionecallvirt
senza prefisso, che prevede un riferimento dithisType
.Gli argomenti del metodo
arg1
tramiteargN
vengono inseriti nello stack, come con un'istruzionecallvirt
senza prefisso.
Il prefisso constrained
è progettato per consentire l'applicazione di istruzioni callvirt
in modo uniforme indipendente dal fatto che thisType
sia un tipo valore o un tipo riferimento.
Quando un'istruzione callvirt
method
è stata preceduta da constrained
thisType
, l'istruzione viene eseguita come segue:
Se
thisType
è un tipo riferimento (anziché un tipo valore),ptr
viene dereferenziato e passato come puntatore "this" alcallvirt
dimethod
.Se
thisType
è un tipo valore ethisType
implementamethod
,ptr
viene passato come puntatore "this" a un'istruzionecall
method
, per l'implementazione dimethod
da parte dithisType
.Se
thisType
è un tipo valore ethisType
non implementamethod
,ptr
viene dereferenziato, boxed e passato come puntatore "this" all'istruzionecallvirt
method
.
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 fa sì che venga eseguita una copia dell'oggetto originale. Tuttavia, poiché nessuno dei metodi di Object, ValueTypee Enum modificare lo stato dell'oggetto, questo fatto non può essere rilevato.
Il prefisso constrained
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 codice operativo constrained
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 prefisso constrained
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 prefisso constrained
evita anche potenziali problemi di controllo delle versioni con i tipi valore. Se il prefisso constrained
non viene utilizzato, è necessario generare un'istruzione IL diversa a seconda che un tipo di valore esesti o meno un metodo di System.Object. Ad esempio, se un tipo valore V
esegue l'override del metodo Object.ToString(), viene generata un'istruzione call
V.ToString()
; in caso contrario, vengono generate un'istruzione box
e un'istruzione callvirt
Object.ToString()
. Un problema di controllo delle versioni può verificarsi nel caso precedente se l'override viene rimosso in un secondo momento e in quest'ultimo caso se viene aggiunto un override in un secondo momento.
Il prefisso constrained
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 MethodImpl
. Se il prefisso constrained
non viene usato, il compilatore deve scegliere a quale dei metodi del tipo valore associare in fase di compilazione. L'uso del prefisso constrained
consente al MSIL di eseguire il binding al metodo che implementa il metodo di interfaccia in fase di esecuzione, anziché in fase di compilazione.
L'overload del metodo Emit seguente può usare il codice operativo constrained
: