OpCodes.Readonly Campo
Definición
Importante
Parte de la información hace referencia a la versión preliminar del producto, que puede haberse modificado sustancialmente antes de lanzar la versión definitiva. Microsoft no otorga ninguna garantía, explícita o implícita, con respecto a la información proporcionada aquí.
Especifica que la operación de dirección de matriz subsiguiente no realiza ninguna comprobación de tipo en tiempo de ejecución y devuelve un puntero administrado cuya mutabilidad está restringida.
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
Valor de campo
Comentarios
En la tabla siguiente se muestra el formato de ensamblado hexadecimal y lenguaje intermedio de Microsoft (MSIL), junto con un breve resumen de referencia:
Formato | Formato de ensamblado | Descripción |
---|---|---|
FE 1E | readonly. | Especifique que la operación de dirección de matriz posterior no realiza ninguna comprobación de tipos en tiempo de ejecución y que devuelve un puntero administrado con mutabilidad restringida. |
Este prefijo solo puede aparecer inmediatamente antes de la ldelema
instrucción y las llamadas al método especial Address
en matrices. Su efecto en la operación posterior es dos veces:
En tiempo de ejecución, no se realiza ninguna operación de comprobación de tipos. Tenga en cuenta que normalmente hay una comprobación de tipo implícito para las
ldelema
instrucciones ystelem
cuando se usan en matrices de tipos de referencia. Nunca hay una comprobación de tipo en tiempo de ejecución para las clases de valor, por lo quereadonly
es una operación sin operación en ese caso.El comprobador trata el resultado de la operación de dirección como un puntero administrado con mutabilidad restringida.
Se dice que el puntero tiene una mutabilidad restringida porque el tipo de definición controla si el valor se puede mutar. Para las clases de valor que no exponen campos o métodos públicos que actualizan el valor en contexto, el puntero es de solo lectura (por lo tanto, el nombre del prefijo). En concreto, las clases que representan tipos primitivos (por ejemplo, System.Int32) no exponen mutadores y, por tanto, son de solo lectura.
Un puntero administrado restringido de esta manera solo se puede usar de las siguientes maneras:
object
Como parámetro para lasldfld
instrucciones , ,call
ldflda
stfld
, oconstrained callvirt
.pointer
Como parámetro de laldobj
instrucción o de una de lasldind
instrucciones.source
Como parámetro de lacpobj
instrucción .
Todas las demás operaciones no permitidas, incluidas las stobj
initobj
operaciones , o mkrefany
o cualquiera de las stind
instrucciones.
El propósito del readonly
prefijo es evitar una comprobación de tipos al capturar un elemento de una matriz en código genérico. Por ejemplo, la expresión arr[i].m()
, donde el tipo de elemento de la matriz arr
es un tipo genérico que se ha restringido para tener una interfaz con el método m
, podría compilarse en el siguiente MSIL.
ldloc arr
ldloc i
readonly.
ldelema !0 // Loads the pointer to the object.
… // Load the arguments to the call.
constrained. !0
callvirt m
Sin el readonly
prefijo, la ldelema
instrucción realizaría una comprobación de tipos en el caso de que !0 fuera un tipo de referencia. No solo es ineficaz esta comprobación de tipos, pero es semánticamente incorrecta. La comprobación de tipo de ldelema
es una coincidencia exacta, que es demasiado fuerte. Si la matriz contiene subclases de tipo !0, el código anterior producirá un error en la comprobación de tipos.
La dirección del elemento de matriz se captura, en lugar del propio elemento, con el fin de tener un identificador para que funcione tanto arr[i]
para los tipos de valor como para los tipos de referencia, y por lo tanto se puede pasar a la constrained callvirt
instrucción .
En general, no sería seguro omitir la comprobación en tiempo de ejecución si la matriz tenía elementos de un tipo de referencia. Para ser seguro, es necesario asegurarse de que no se realicen modificaciones en la matriz a través de este puntero. Las reglas del comprobador garantizan esto. El puntero administrado restringido se puede pasar como objeto de llamadas de método de instancia, por lo que no es estrictamente de solo lectura para los tipos de valor, pero no hay ningún problema de seguridad de tipos para los tipos de valor.
La sobrecarga del método siguiente Emit puede usar el readonly
código de operación: