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 Microsoft linguagem intermediária (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 nenhuma verificação de tipo 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 verificação de tipo é executada. Observe que normalmente há uma verificação de tipo implícita para as ldelema instruções e stelem quando usadas em matrizes de tipo de referência. Nunca há uma verificação de tipo de tempo de execução para classes de valor, portanto readonly , é uma no-op 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 uma verificação de tipo 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 uma verificação de tipo no caso em que !0 era um tipo de referência. Esse tipo não é apenas ineficiente, mas está semanticamente incorreto. A verificação ldelema de tipo é uma correspondência exata, que é muito forte. Se a matriz mantiver subclasses do tipo !0, o código acima falhará na verificação de tipo.

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 a verificação em tempo de execução 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