28

I want to call a function, with as parameters a string and an Int32. The string is just a literal, the Int32 should be a field. So I thought it should be something like:

.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 
}

But this throws the error that this is not valid code. When adding

ldarg.0 

before ldfld it runs just fine. Why is this, and is this going to get me into trouble when having more fields?

Jan Jongboom
  • 26,598
  • 9
  • 83
  • 120

1 Answers1

47

Instance methods have an implicit parameter called "this". It is loaded as the first argument to the stack, thus you have ldarg.0 for "this".

Joel Marcey
  • 1,748
  • 14
  • 13
  • doesn't ldarg.0 correspond to the first parameter passed to a method ? – lysergic-acid Nov 26 '14 at 07:12
  • 2
    As Joel Marcey explains, there is an implicit first parameter "this". A bit like when you declare an extension method and include parameter (this targetType targetObject, ... which you then later do not have to reference. – Phil Nov 04 '15 at 09:08
  • ... e.g. You can have a method: public static char MyStringMethod(this String inputString, int index) { return inputString[index]; } - when you call it, the first parameter is implicit - var myCharacter = myString.MyStringMethod(5); - but is still loaded when the method is executed. – Phil Nov 04 '15 at 09:16