The readonly.
prefix and unbox
instructions can produce what is called a controlled-mutability managed pointer. Unlike ordinary managed pointer types, a controlled-mutability managed pointer is not verifier-assignable-to (§III.1.8.1.2.3) ordinary managed pointers; e.g., it cannot be passed as a byref argument to a method. At control flow points, a controlled-mutability managed pointer can be merged with a managed pointer of the same type to yield a controlled-mutability managed pointer.
Controlled-mutability managed pointers can only be used in the following ways:
-
As the object parameter for an
ldfld
,ldflda
,stfld
,call
,callvirt
, orconstrained. callvirt
instruction. -
As the pointer parameter to a
ldind.*
orldobj
instruction. -
As the source parameter to a
cpobj
instruction.
All other operations (including stobj
, stind.*
, initobj
, and mkrefany
) are invalid.
The pointer is called a controlled-mutability managed pointer because the defining type decides whether the value can be mutated. For value classes that expose no public fields or methods that update the value in place, the pointer is read-only (hence the name of the prefix). In particular, the classes representing primitive types (such as System.Int32
) do not expose mutators and thus are read-only.