変数は実際にはスタックに配置されているためオブジェクトの一部になっているので、クロージャーにはボクシングが関係しているわけではありませんか?
その文の間違いの数が多い。あなたにいくつかの神話を混乱させましょう。
(1)値型の変数は「スタックには行きません」。 寿命が短い変数はスタックになります。この変数の寿命は短いですか?いいえ、それは任意に長い寿命を持っています。それはスタックに行くのですか?参照タイプのオブジェクトのフィールドがスタックにありません。それはヒープです。どうして?再び、フィールドは任意に長い寿命を有するからである。
(3)ヒープ上にある変数内の整数は囲む必要はありません。整数がボックス化されるかどうかは、の整数が参照型に変換されたかどうかによって異なります。 変数の場所は関係ありません。重要なのは、変数の型が参照型か値型かどうかです。
それでは、あなたのコードを見てみましょう:
public static Func<int,int> GetAFunc()
{
var myVar = 1;
Func<int, int> inc = delegate(int var1)
{
myVar = myVar + 1;
return var1 + myVar;
};
return inc;
}
このコードは同等です:整数を参照型に変換するとき
private class Closure
{
public int myVar;
public int SomeFunction (int var1)
{
this.myVar = this.myVar + 1;
return var1 + this.myVar;
}
}
public static Func<int,int> GetAFunc()
{
Closure locals = new Closure();
locals.myVar = 1;
Func<int, int> inc = locals.SomeFunction;
return inc;
}
いつでもそこにありますか?いいえ、ボクシングはありません。
ただし、ボクシングを避ける点は、で、余分なオブジェクトを割り当てるコストを避けることです。。私たちはでしたは余分なオブジェクトを割り当てました:閉鎖!ここにはボクシングペナルティはありませんが、クロージャーのためにペナルティがあります。クロージャーを割り当てることは、収集圧力を増加させる。そしてもちろん、ローカルへの参照はすべて、今や余分な間接的なものになっていなければなりません。
変数は**ではありません**スタックにあります。 C#コンパイラはコードを書き換え、* myVar *はクラスのフィールドになります。どこでもボクシングはありません。これを表示するにはildasm.exeを使用してください。 –
値の型が別の型のフィールドである場合、ボクシングはありません...クロージャのために生成されたコードを再度見たい場合があります。 –