2009-05-12 6 views
4

は、C#はLambdasに値渡ししますか?私はいくつかのコードを持っている

int count = 0; 

list.ForEach(i => i.SomeFunction(count++)); 

これはカウントをインクリメントないようです。カウントはここで値渡されますか?ラムダで{}を使用すると違いはありますか?

int count = 0; 

list.ForEach(i => 
      { 
        i.SomeFunction(count++); 
      }); 

アップデート1

申し訳ありませんが、私のミス、それは本来の数を更新しません。

+0

。 –

答えて

6

countはintで、intは値の型です。つまり、実際に値渡しされています。あなたの第一の例と第二の例の間には意味の違いはありません。

(つまり、元の参照をクロージャまでキャプチャする必要があるため、countをインクリメントする必要があります。明確にするために、カウントは値によってSomeFunctionに渡されますが、式の中でラムダ式を使用するときにラムダ式に "渡される"ことはありません。

0

いいえ、違いはありません。引数は、ラムダで使用されるデリゲート定義で明示的に "ref"または "out"にしない限り、通常は値で指定します。

1

これは、closureとしてカウントをクローズする必要があります。

0

ラムダは匿名関数なので、引数を関数に渡すのと同じ規則に従います。

+0

キャプチャされた変数は非常に異なるルールに従います... –

5

どちらの場合も、クロージャと呼ばれるものを作成しています。基本的には、countはクラスにラップされており、そのクラスはラムダ式で使用されています。

Bill WagnerにはMore Effective C#という素晴らしい本があり、彼はclosuresを詳しく説明するブログ記事を持っています。増分べき

4

、プルーフ:

class Foo 
{ 
    public void SomeFunction(int i) { } 
} 
static void Main() 
{ 
    int count = 0; 
    List<Foo> list = new List<Foo> {new Foo()}; 
    list.ForEach(i => i.SomeFunction(count++)); 
    Console.WriteLine(count); // 1 
} 

ラムダ作用は、(既に述べたように)「捕捉」本質的なコードを作成、カウントする:

class Foo 
{ 
    public void SomeFunction(int i) { } 
} 
class CaptureScope 
{ 
    public int count; 
    public void AnonMethod(Foo foo) 
    { 
     foo.SomeFunction(count++); 
    } 
} 
static void Main() 
{ 
    CaptureScope scope = new CaptureScope(); 
    scope.count = 0; 
    List<Foo> list = new List<Foo> {new Foo()}; 
    list.ForEach(scope.AnonMethod); 
    Console.WriteLine(scope.count); // 1 
} 

上記粗い近似でありますコンパイラがデリゲートラムダをどのように解釈するかを示します。ご覧のとおり、countはクラスのフィールドで、です。

0

この場合、countの変数はであり、です。 structであっても、キャプチャされた変数はの参照のように動作します。したがって、foreachの後には、増分されたcountが確実に表示されます。

5

変数カウントは、状況に応じてラムダ式によって取得されます。 countへの変更は、呼び出し元に表示されます。ですから、例えば:各反復にあなたがcountをインクリメントしているので

int count = 0; 
list.ForEach(i => i.SomeFunction(count++)); 
Console.WriteLine(count); 

は、リストのサイズを表示します。

しかし、SomeFunctionへの呼び出しは、SomeFunctionに値によって(インクリメント前countの値である)count++の評価値を通過します。つまり、SomeFunctioncountの値を変更できません。

クロージャと変数キャプチャの詳細については、closures articleを参照してください。

3

ここで小さな修正を加えたいと思っていました。変数countは値ではなく、ラムダ式への参照によっても渡されません。これはパラメータではないからです。代わりに、値はであり、クロージャ内のラムダによってがキャプチャされます。

あなたは対象 にレイモンドのシリーズをチェックアウトする必要があります - 私はそれはあなたに多くのタイピングを保存していないとトラブルのない終わりを引き起こすことはできません、あなたがそれらを使用すると同時に、変数を変更に対して助言http://blogs.msdn.com/oldnewthing/archive/2006/08/02/686456.aspx

関連する問題