tags:

views:

84

answers:

2

When you have an object instance in C#, you can use the this keyword inside the instance scope. How does the compiler handles it? Is there any assistance for this at runtime?

I am mainly wondering how C# does it vs in python you have to provide self for every function manually.

+3  A: 

This is supported at the CLR level. The argument variable at slot 0 represents the "this" pointer. C# essentially generates calls to this as ldarg.0

JaredPar
Does java works the same way?
marcos
+1: I read the question differently - not sure exactly what Joan was referring to, here...
Reed Copsey
+2  A: 

The compiler always creates IL that sets the field using the class name, in any case - whether you specify this or not. The this. is optional unless there is another variable in your scope with the same name as an instance variable, in which case the compiler knows to set the instance variable.

For example, if you have a class in the TestProject namespace named TestClass, and it contains a field named testOne, the following:

TestClass(string value) // Constructor
{
    this.testOne = value;
}

Gets compiled into IL like so:

L_0000: ldarg.0
// ... other initialization stuff 
L_0004: ldarg.1
L_0005: stfld string TestProject.TestClass::testOne

The instance variable is always set using the full class information, whether or not "this" is specified.


Edit for comments:

In C#, you can always use this in a method as a keyword because the first argument in the argument list is "this", even if its not specified. For example, say we make a method like so:

class Test
{
    void TestMethod(Test instance) { 
       // Do something
    }
    void CallTestMethod() {
        TestMethod(this);
    }

When you look at the IL for CallTestMethod, it will look like this:

.method public hidebysig instance void CallTestMethod() cil managed
{
    .maxstack 8
    L_0000: nop 
    L_0001: ldarg.0 
    L_0002: ldarg.0 
    L_0003: call instance void CSharpConsoleApplication.Test::TestMethod(class CSharpConsoleApplication.Test)
    L_0008: nop 
    L_0009: ret 
}

In this case, the compiler loads ldarg.0 onto the stack twice, which becomes the argument passed into TestMethod (it will become its ldarg.1). Basically, there is always a "this" internally, in any class method.

Reed Copsey
After seeing JaredPar's comment, I realized you may be referring to using "this" as an argument. If so, it's loaded las ldarg.0, as he mentioned, and is a variable that always exists in instance methods.
Reed Copsey
Sorry I meant to refer the this keyword, not as an argument. As in how C# knows/provides it but in python, you have to provide it manually for no reason.
Joan Venge
If you don't provide self, you can use self, but in C# you use this, without explicitly passing it to the method, etc.
Joan Venge
Joan: Does that answer your question? I just edited to show the IL involved.
Reed Copsey
Thanks Reed. I think it does but I thought the this is specified here:class CSharpConsoleApplication.Testwhich is what's passed to:CSharpConsoleApplication.Test::TestMethod?
Joan Venge
If you look at the last IL (this is the CallTestMethod IL), it uses ldarg.0 (which is "this"), by loading it onto the stack twice. The CLR always sets up ldarg.0 (the first argument at pos 0) to "this" in an instance method. "this" is loaded twice, then used to call the method (CSharpConsoleApplication.Test::TestMethod) - the first "this" becomes the "this" inside TestMethod, the second "this" on the stack is the argument passed into TestMethod.
Reed Copsey