OpCodes.Readonly Поле
Определение
Важно!
Некоторые сведения относятся к предварительной версии продукта, в которую до выпуска могут быть внесены существенные изменения. Майкрософт не предоставляет никаких гарантий, явных или подразумеваемых, относительно приведенных здесь сведений.
Указывает, что последующая операция, связанная с адресом массива, не выполняет никаких проверок во время выполнения и возвращает управляемый указатель, изменение которого запрещено.
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
Значение поля
Комментарии
В следующей таблице перечислены шестнадцатеричный формат инструкции и сборки msil и краткие справочные сведения:
Формат | Формат сборки | Описание |
---|---|---|
FE 1E | readonly. | Укажите, что последующая операция с адресом массива не выполняет проверка типов во время выполнения и что она возвращает управляемый указатель с ограниченной изменяемостью. |
Этот префикс может отображаться только непосредственно перед ldelema
инструкцией и вызовами специального Address
метода в массивах. Его влияние на последующую операцию является двояким:
Во время выполнения операция проверка типа не выполняется. Обратите внимание, что обычно существует неявный тип проверка для инструкций
ldelema
иstelem
при использовании в массивах ссылочных типов. Тип времени выполнения никогда не проверка для классов значений, поэтомуreadonly
в этом случае это не работает.Проверяющий объект обрабатывает результат операции адреса как управляемый указатель с ограниченной изменяемостью.
Считается, что указатель имеет ограниченную изменяемость, так как определяющий тип определяет, можно ли изменить значение. Для классов значений, которые не предоставляют открытых полей или методов, которые обновляют значение на месте, указатель доступен только для чтения (следовательно, имя префикса). В частности, классы, представляющие примитивные типы (например, System.Int32), не предоставляют мутаторов и, таким образом, доступны только для чтения.
Управляемый указатель, ограниченный таким образом, можно использовать только следующими способами:
object
В качестве параметра для инструкцийldfld
,ldflda
,stfld
,call
, илиconstrained callvirt
.pointer
В качестве параметра для инструкцииldobj
или для одной из инструкцийldind
.source
В качестве параметра инструкцииcpobj
.
Все остальные операции запрещены, включая stobj
операции , initobj
или mkrefany
или любые инструкции stind
.
Назначение readonly
префикса — избежать проверка типа при получении элемента из массива в универсальном коде. Например, выражение arr[i].m()
, где тип элемента массива arr
является универсальным типом, который был ограничен наличием интерфейса с методом m
, может компилироваться в следующий MSIL.
ldloc arr
ldloc i
readonly.
ldelema !0 // Loads the pointer to the object.
… // Load the arguments to the call.
constrained. !0
callvirt m
readonly
Без префикса инструкция будет выполнять тип проверка в случае, ldelema
когда !0 был ссылочным типом. Этот тип не только проверка неэффективным, но и семантически неверным. Тип проверка для ldelema
является точным совпадением, которое является слишком сильным. Если массив содержал подклассы типа !0, приведенный выше код завершится ошибкой типа проверка.
Адрес элемента массива получается вместо самого элемента, чтобы иметь дескриптор для arr[i]
, который работает как для типов значений, так и ссылочных типов, и, таким образом, может быть передан инструкции constrained callvirt
.
В целом было бы небезопасно пропускать проверка времени выполнения, если массив содержит элементы ссылочного типа. Чтобы обеспечить безопасность, необходимо убедиться, что с помощью этого указателя не вносятся никакие изменения в массив. Это гарантируется правилами проверки. Управляемый указатель с ограниченным доступом может передаваться в качестве объекта вызовов метода экземпляра, поэтому он строго не предназначен для чтения для типов значений, но для типов значений нет проблем с безопасностью типов.
Следующая Emit перегрузка readonly
метода может использовать код операции: