2016-06-22 12 views
0

私はthis questionと尋ねた後、この推奨article about closuresを読んで、私はC#で閉鎖を作ることがボクシングを含む場合、自分自身に尋ね始めました。クロージャーにはボクシングが必要ですか?

それは記事で述べたように、コードのこの行がmyVarを行うことで、クロージャを作成し、それがスコープの外に存在する:

public static Func<int,int> GetAFunc() 
{ 
    var myVar = 1; 
    Func<int, int> inc = delegate(int var1) 
          { 
           myVar = myVar + 1; 
           return var1 + myVar; 
          }; 
    return inc; 
} 

したようにそこに説明し、コンパイラ生成されたクラスのオブジェクトを搬送するためにインスタンス化されスコープ外のこの変数の値。ここで私の質問が来る:変数は実際にスタックの上にあるので、それはオブジェクトの一部にして、クロージャーがボクシングを含むことを意味しないのですか?

+0

変数は**ではありません**スタックにあります。 C#コンパイラはコードを書き換え、* myVar *はクラスのフィールドになります。どこでもボクシングはありません。これを表示するにはildasm.exeを使用してください。 –

+0

値の型が別の型のフィールドである場合、ボクシングはありません...クロージャのために生成されたコードを再度見たい場合があります。 –

答えて

8

変数は実際にはスタックに配置されているためオブジェクトの一部になっているので、クロージャーにはボクシングが関係しているわけではありませんか?

その文の間違いの数が多い。あなたにいくつかの神話を混乱させましょう。

(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; 
} 

いつでもそこにありますか?いいえ、ボクシングはありません。

ただし、ボクシングを避ける点は、で、余分なオブジェクトを割り当てるコストを避けることです。。私たちはでしたは余分なオブジェクトを割り当てました:閉鎖!ここにはボクシングペナルティはありませんが、クロージャーのためにペナルティがあります。クロージャーを割り当てることは、収集圧力を増加させる。そしてもちろん、ローカルへの参照はすべて、今や余分な間接的なものになっていなければなりません。

+0

あなたは正しいです!この問題についてもう一度質問できますか?コンパイル時にクラス "Closure"が生成されるためボクシングは含まれないため、変数は最初にスタックに割り当てられずにヒープに移動されます。私は正しいことを理解しましたか? – meJustAndrew

+0

@meJustAndrewいいえ。値の型は決して参照型に変換されないため、ボクシングは含まれません。スタック/ヒープは、このコンセプトとはまったく関係ありません。 –

+0

私はボクシングの適切な理解を持っていた、それは正しいです。私は、値の型が参照型に変換されるときにこれが起こると考えました。しかし、確認番号1については、なぜ値型変数がスタックにならないのでしょうか?[this article from msdn](https://msdn.microsoft.com/ro-ro/library/4d43ts61 (v = 90).aspx)ここで、「値型はその内容をスタックに割り当てられたメモリに格納します」と表示されます。私はこの記事が時代遅れであるかもしれないことを知っています。私はあなたの答えを今まで評価しています。物事を尋ね続けることで無礼になりたくはありません。 – meJustAndrew

関連する問題