2016-06-21 5 views
-2

私はthis questionでC#5.0にはloop variable closureが導入されていますが、それが意味するものを見つけるために質問のリンクにアクセスしました。私には恥ずかしがりますが、私はループ変数クロージャーの多くを理解することができませんでした。なぜなら、前回のコンパイル警告が生成されなかったセクションブロックからの警告を生成するために、新しいバージョンのプログラミング言語でコードが変更される私が理解しているので、ループクロージャはforeachのフォーマットではなく、配列に含まれる変数です。これは正しいですか?ループ変数クロージャとは何ですか?

答えて

3

はシンプルforeachループください: C#5の前に

foreach(var i in Enumerable.Range(0,10)) 
{ 
    Console.WriteLine(i); 
} 

を、ループ全体の実行(反復ごと)を使用しただけで変数iがありました。

C#5の導入後、このループには10個の個別の変数...ループの繰り返しごとに異なるものが追加されます。これらの変数の寿命はより短く、すべて同じ名前ですが、それでも一意の変数です。

一見したところで差はあまり見えないかもしれませんが、クロージャを使って作業しているときに、古い動作に予期しない結果が生じる可能性があります。

あなたは、このコードサンプルで違いを見ることができます:

var results = new List<Func<int>>(); 
foreach(var i in Enumerable.Range(0,10)) 
{ 
    results.Add(() => i); 
} 
foreach(var item in results) 
{ 
    Console.WriteLine(item()); 
} 

このコードはコンパイルおよびVS 2010とVS 2012の両方から実行(およびそれ以降)、しかし、あなたが使用するかによって異なる結果が得られますでしょう。

closureコンパイラが変数を通常のスコープ領域から「クローズオーバー」または「ホイスト」してそのライフタイムを延長すると、何が起こりますか?ラムダ式(=>演算子で示されています)で作業しているときはいつも、クロージャも関わっていることがよくあります。私のサンプルでは、​​変数iは、リストに配置された匿名関数が利用できるようにクロージャーで使用されています。

変数と値の違いを理解することが重要です。 VS2010でコードを実行できるのは、変数が1つだけだった場合、その区別は非常に明確です...ループの以前の反復からの変数の値は、関数の前のループの後の反復によって変更され続ける可能性がありますが呼び出されます。誰もが尋ねる前に


は:パフォーマンス上の違いはありません。違いは、コンパイラの抽象度の詳細です。はパフォーマンスには影響しますが、測定可能な方法では影響しません。

+0

ここは閉鎖に関する良い記事です。http://www.codethinked.com/c-closures-explained –

関連する問題