2009-10-29 2 views
2

Lorsque vous avez une instance d'objet en C#, vous pouvez utiliser le mot-clé this dans la portée de l'instance. Comment le compilateur le gère-t-il? Y a-t-il de l'aide pour cela à l'exécution?Comment ce mot-clé est-il fourni pour les instances d'objet en C#?

Je me demande principalement comment C# le fait vs en python vous devez vous fournir pour chaque fonction manuellement.

Répondre

2

Le compilateur crée toujours IL qui définit le champ en utilisant le nom de la classe, dans tous les cas - que vous le spécifiiez ou non. Le this. est facultatif sauf s'il existe une autre variable dans votre étendue avec le même nom qu'une variable d'instance, auquel cas le compilateur sait définir la variable d'instance.

Par exemple, si vous avez une classe dans l'espace de noms TestProject nommé TestClass, et il contient un champ nommé testone, ce qui suit:

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

se compile dans IL comme ceci:

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

La variable d'instance est toujours définie à l'aide des informations de classe complètes, que "this" soit spécifié ou non.


Modifier pour les commentaires:

En C#, vous pouvez toujours l'utiliser dans une méthode comme mot-clé parce que le premier argument dans la liste des arguments est « ce », même si son non spécifié. Par exemple, disons que nous faisons une méthode comme ceci:

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

Lorsque vous regardez l'IL pour CallTestMethod, il ressemblera à ceci:

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

Dans ce cas, les charges du compilateur ldarg.0 sur la empile deux fois, ce qui devient l'argument passé en TestMethod (il deviendra ldarg.1). Fondamentalement, il y a toujours un "ceci" en interne, dans n'importe quelle méthode de classe.

+0

Après avoir vu le commentaire de JaredPar, je me suis rendu compte que vous utilisiez "this" comme argument. Si c'est le cas, il est chargé las ldarg.0, comme il l'a mentionné, et est une variable qui existe toujours dans les méthodes d'instance. –

+0

Désolé, je voulais renvoyer ce mot-clé, pas comme un argument. Comme dans C# sait/fournit mais en python, vous devez le fournir manuellement sans raison. –

+0

Si vous ne fournissez pas self, vous pouvez utiliser self, mais en C#, vous l'utilisez, sans le passer explicitement à la méthode, etc. –

3

Ceci est pris en charge au niveau CLR. La variable d'argument à l'emplacement 0 représente le pointeur "this". C# génère essentiellement des appels à ce que ldarg.0

+0

Est-ce que java fonctionne de la même façon? – marcosbeirigo

+0

+1: J'ai lu la question différemment - je ne sais pas exactement de quoi parlait Joan, ici ... –