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
Mais pourquoi le pousser sur la pile? On dirait un gaspillage d'espace pour moi. – Snake
@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. –
@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