2009-11-23 10 views
21

Voglio chiamare una funzione, con i parametri come string e Int32. Lo string è solo un valore letterale, lo Int32 dovrebbe essere un field. Quindi ho pensato che fosse qualcosa di simile:Perché devo fare ldarg.0 prima di chiamare un campo in MSIL?

.method public hidebysig instance string TestVoid() cil managed 
{ 
    .maxstack 1 
    .locals init (
     [0] string CS$1$0000) 
    L_0000: nop 
    L_0001: ldstr "myString" 
    L_0006: ldfld int32 FirstNamespace.FirstClass::ByteField 
    L_000b: call string [Class1]Class1.TestClass::Functie<int32>(string, int32) 
    L_0010: ret 
} 

Ma questo genera l'errore che questo non è codice valido. Quando si aggiunge

ldarg.0 

prima dello ldfld funziona correttamente. Perché è questo, e questo mi metterà nei guai quando ho più campi?

risposta

35

I metodi di istanza hanno un parametro implicito denominato "questo". Viene caricato come primo argomento dello stack, quindi hai ldarg.0 per "questo".

+0

non ldarg.0 corrisponde al primo parametro passato a un metodo? –

+2

Come spiega Joel Marcey, esiste un primo parametro implicito "questo". Un po 'come quando dichiari un metodo di estensione e includi un parametro (questo targetType targetObject, ... che poi non dovrai fare riferimento. – Phil

+0

... es. Puoi avere un metodo: public static char MyStringMethod (this String inputString, int index) {return inputString [index];} - quando lo chiamate, il primo parametro è implicito - var myCharacter = myString.MyStringMethod (5); - ma è ancora caricato quando viene eseguito il metodo. – Phil

Problemi correlati