Compartilhar via


OpCodes.Readonly Campo

Definição

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:

  1. 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 e stelem 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.

  2. 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 as ldfldinstruções , ldflda, callstfld, ouconstrained callvirt .

  • Como o pointer parâmetro para a ldobj instrução ou para uma das ldind instruções.

  • Como o source parâmetro para a cpobj instrução .

Todas as outras operações não permitidas, incluindo as stobjoperações , initobjou 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:

Aplica-se a