OpCodes.Readonly Campo
Definição
Importante
Algumas informações se referem a produtos de pré-lançamento que podem ser substancialmente modificados antes do lançamento. A Microsoft não oferece garantias, expressas ou implícitas, das informações aqui fornecidas.
Especifica que a operação de endereço da matriz subsequente não executa nenhuma verificação de tipo no tempo de execução e que ela retorna um ponteiro gerenciado cuja mutabilidade é restrita.
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 do campo
Comentários
A tabela a seguir lista o formato de assembly hexadecimal e msil da instrução, juntamente com um breve resumo de referência:
Formatar | Formato de assembly | Descrição |
---|---|---|
FE 1E | readonly. | Especifique que a operação de endereço de matriz subsequente não executa nenhum tipo marcar em tempo de execução e que ela retorna um ponteiro gerenciado com mutabilidade restrita. |
Esse prefixo só pode aparecer imediatamente antes da ldelema
instrução e chama o método especial Address
em matrizes. Seu efeito na operação subsequente é duplo:
Em tempo de execução, nenhuma operação de marcar tipo é executada. Observe que normalmente há um tipo implícito marcar para as
ldelema
instruções estelem
quando usado em matrizes de tipo de referência. Nunca há um tipo de tempo de execução marcar para classes de valor, portantoreadonly
, é um não operacional nesse caso.O verificador trata o resultado da operação address-of como um ponteiro gerenciado com mutabilidade restrita.
Diz-se que o ponteiro tem mutabilidade restrita porque o tipo de definição controla se o valor pode ser modificado. Para classes de valor que não expõem campos ou métodos públicos que atualizam o valor em vigor, o ponteiro é somente leitura (daí o nome do prefixo). Em particular, as classes que representam tipos primitivos (por exemplo, System.Int32) não expõem mutadores e, portanto, são somente leitura.
Um ponteiro gerenciado restrito dessa forma só pode ser usado das seguintes maneiras:
Como o
object
parâmetro para asldfld
instruções ,ldflda
,call
stfld
, ouconstrained callvirt
.Como o
pointer
parâmetro para aldobj
instrução ou para uma dasldind
instruções.Como o
source
parâmetro para acpobj
instrução .
Todas as outras operações não permitidas, incluindo as stobj
operações , initobj
ou mkrefany
ou qualquer uma das stind
instruções.
A finalidade do readonly
prefixo é evitar um tipo marcar ao buscar um elemento de uma matriz em código genérico. Por exemplo, a expressão arr[i].m()
, em que o tipo de elemento da matriz arr
é um tipo genérico que foi restrito a ter uma interface com o método m
, pode ser compilada para o MSIL a seguir.
ldloc arr
ldloc i
readonly.
ldelema !0 // Loads the pointer to the object.
… // Load the arguments to the call.
constrained. !0
callvirt m
Sem o readonly
prefixo , a ldelema
instrução executaria um tipo marcar no caso em que !0 era um tipo de referência. Não só esse tipo é marcar ineficiente, mas é semanticamente incorreto. O tipo para o qual marcar ldelema
é uma correspondência exata, que é muito forte. Se a matriz tivesse subclasses do tipo !0, o código acima falharia no tipo marcar.
O endereço do elemento de matriz é buscado, em vez do próprio elemento, para ter um identificador para arr[i]
que funcione para tipos de valor e tipos de referência e, portanto, pode ser passado para a constrained callvirt
instrução .
Em geral, não seria seguro ignorar o tempo de execução marcar se a matriz tivesse elementos de um tipo de referência. Para ser seguro, é necessário garantir que nenhuma modificação na matriz seja feita por meio desse ponteiro. As regras do verificador garantem isso. O ponteiro gerenciado restrito pode ser passado como o objeto do método de instância chama, portanto, não é estritamente falando somente leitura para tipos de valor, mas não há nenhum problema de segurança de tipo para tipos de valor.
Emit A seguinte sobrecarga de método pode usar o readonly
opcode: