Sdílet prostřednictvím


OpCodes.Readonly Pole

Definice

Určuje, že následná operace adresy pole neprovádí za běhu žádnou kontrolu typu a že vrátí spravovaný ukazatel, jehož proměnlivost je omezená.

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 

Hodnota pole

Poznámky

Následující tabulka uvádí šestnáctkový formát sestavení instrukce a formát sestavení MSIL (Microsoft Intermediate Language) spolu se stručným souhrnem referenčních informací:

Formát Formát sestavení Description
FE 1E Readonly. Určete, že následná operace adresy pole neprovádí za běhu žádnou kontrolu typu a že vrátí spravovaný ukazatel s omezenou proměnlivostí.

Tato předpona se může zobrazit pouze bezprostředně před ldelema instrukcemi a voláním speciální Address metody na polích. Jeho vliv na následnou operaci je dvojí:

  1. Za běhu se neprovádí žádná operace kontroly typu. Všimněte si, že při použití polí referenčního typu obvykle probíhá implicitní kontrola typu pro ldelema pokyny a stelem . Nikdy neexistuje kontrola typu za běhu pro třídy hodnot, takže readonly v takovém případě se jedná o no-op.

  2. Ověřovatel považuje výsledek operace za spravovaný ukazatel s omezenou proměnlivostí.

O ukazateli se říká, že má omezenou proměnlivost, protože definující typ určuje, jestli může být hodnota mutována. U tříd hodnot, které nezpřístupňují žádná veřejná pole nebo metody, které aktualizují hodnotu, je ukazatel jen pro čtení (odtud název předpony). Konkrétně třídy představující primitivní typy (například System.Int32) nezpřístupňují mutátory, a proto jsou jen pro čtení.

Spravovaný ukazatel omezený tímto způsobem lze použít pouze následujícími způsoby:

  • object Jako parametr pro ldfldinstrukce , ldflda, stfldcall, neboconstrained callvirt .

  • pointer Jako parametr instrukce ldobj nebo jednoho z ldind pokynů.

  • source Jako parametr instrukcecpobj.

Všechny ostatní operace byly zakázány, včetně stobjoperací , initobjnebo mkrefany nebo některého z stind pokynů.

Účelem předpony readonly je vyhnout se kontrole typu při načítání elementu z pole v obecném kódu. Například výraz arr[i].m(), kde typ elementu pole arr je obecný typ, který byl omezen tak, aby měl rozhraní s metodou m, se může zkompilovat do následujícího jazyka MSIL.

ldloc arr  
ldloc i  
readonly.  
ldelema !0    // Loads the pointer to the object.  
…             // Load the arguments to the call.  
constrained. !0  
callvirt m  

Bez předpony readonly by instrukce provedla kontrolu typu v případě, ldelema že !0 byl typ odkazu. Nejen, že je tato kontrola typu neefektivní, ale je sémanticky nesprávná. Kontrola ldelema typu je přesná shoda, která je příliš silná. Pokud pole uchovává podtřídy typu !0, výše uvedený kód by při kontrole typu selhal.

Místo samotného elementu se načte adresa elementu pole, aby měl popisovač arr[i] , který funguje jak pro hodnotové typy, tak pro odkazové typy, a proto může být předán constrained callvirt instrukce.

Obecně by bylo nebezpečné přeskočit kontrolu za běhu, pokud pole obsahuje prvky typu odkazu. Aby byl tento ukazatel bezpečný, je nutné zajistit, aby prostřednictvím tohoto ukazatele nebyly provedeny žádné změny pole. To zajišťují pravidla ověřovatele. Omezený spravovaný ukazatel může být předán jako objekt volání metody instance, takže to není striktně řečeno jen pro čtení pro typy hodnot, ale neexistuje žádný typ bezpečnostní problém pro typy hodnot.

Následující Emit přetížení metody může použít readonly opcode:

Platí pro