2010-11-15 7 views
1
cette classe

Considérez:.NET IL propriété setter

public class Foo 
{ 
    // Fields 
    private string _bar; 

    // Properties 
    private string Bar 
    { 
     get 
     { 
      return this._bar; 
     } 
     set 
     { 
      this._bar = value; 
     } 
    } 
} 

Maintenant, quand je vais regarder dans le code IL émis par le compilateur pour le poseur de la propriété Bar:

.method private hidebysig specialname instance void set_Bar(string 'value') cil managed 
{ 
    .maxstack 8 
    L_0000: nop 
    L_0001: ldarg.0 
    L_0002: ldarg.1 
    L_0003: stfld string ConsoleApplication2.Program/Foo::_bar 
    L_0008: ret 
} 

Pourquoi est-ce il fait ldarg.0? Que se situe-t-il dans le premier argument (index 0)? Puisque la méthode/setter de propriété ne prend 1 argument ...

va de même pour le getter:

.method private hidebysig specialname instance string get_Bar() cil managed 
{ 
    .maxstack 1 
    .locals init (
     [0] string CS$1$0000) 
    L_0000: nop 
    L_0001: ldarg.0 
    L_0002: ldfld string ConsoleApplication2.Program/Foo::_bar 
    L_0007: stloc.0 
    L_0008: br.s L_000a 
    L_000a: ldloc.0 
    L_000b: ret 
} 

pourquoi le .locals init? Pourquoi le ldarg.0? Pourquoi ne fait-il pas un ldfld du champ de sauvegarde et retourne juste cela? :)

Merci.

-Snake

Répondre

4

Pour le poseur:

Tout membre de l'instance a implicitement "ce paramètre" - c'est ce qui est chargé, au fond. Essayez de le transformer en une propriété statique et vous le verrez disparaître.

Pour le getter, je ne sais pas pourquoi il y a la variable locale ... le support du débogueur peut-être? Certainement compiler en mode optimisé (/o+ /debug- à partir de la ligne de commande) se débarrasse de la variable locale.

+0

Mais pourquoi le pousser sur la pile? On dirait un gaspillage d'espace pour moi. – Snake

+0

@Snake: N'oubliez pas que vous regardez l'IL, pas le code natif final. Ce n'est pas parce qu'IL représente «obtenir un champ d'une instance particulière» en poussant quelque chose sur la pile que cela se produit réellement. –

+0

@Snake: Stack comme dans la pile d'évaluation, pas pile de mémoire vs mémoire tas. ldfld va charger un champ mais il a besoin d'une instance de la classe pour le faire. Il n'y a pas implicite ceci, ergo le ldarg.0 http://msdn.microsoft.com/en-us/library/system.reflection.emit.opcodes.ldfld.aspx Le reste de l'inefficacité ressemble juste à des instructions supplémentaires laissé dans le débogage. – Krypes

Questions connexes