2017-01-22 13 views
1

次の短いコードスニペットでラムダ式を正しく使用すると、私は疑問に思っていましたか?私は関数呼び出しを時間の経過とともに保存し、それらをすべてまとめてUpdate_Calls()に実行したいと思います。最も重要なのは、パラメータvar1-3が、いずれの場合でもExtern_Func()を呼び出したときの値を保持するかどうかを尋ねていますか?ラムダ式のパラメータをC#で正しく使用する方法は?

static List<Action> callsForUpdate = new List<Action>(); 

public static void Extern_Func(int var1, int var2, float var3) 
{ 
    Action callToStore =() => Func(var1, var2, var3); 

    // Remember in call list 
    callsForUpdate.Add(callToStore); 
} 

public static void Update_Calls() 
{ 
    for (int i = 0; i < callsForUpdate.Count; i++) 
    { 
    callsForUpdate.ElementAt(i); 
    } 

    callsForUpdate.Clear(); 
} 

答えて

3

はい。それらは保持されます。あなたのUpdate_Callsに問題があります。

public static void Update_Calls() 
    { 
     for (int i = 0; i < callsForUpdate.Count; i++) 
     { 
      callsForUpdate.ElementAt(i)(); 
     } 

     callsForUpdate.Clear(); 
    } 

あなたは要素を参照していました。それを呼び出さない。

+0

この問題を指摘していただきありがとうございます。興味深いことに、コンパイラは不平を言っていませんでした... –

+0

@ares_gamesなぜそれは文句を言うべきですか? – InBetween

1

あなたがそのメソッド(Extern_Func)でそれらを変更しない限りのでActionが、この場合には、彼らがExtern_Funcのローカル変数であり、var1, var2, var3の現在の値で呼び出されることを意味し、閉鎖あなたが作成していると呼ばれています彼らはその価値を維持します。

1

あなたがしていることは、callsForUpdateリストの各項目が指す式を作成することです。式は不変です。式で指定した値を変更するには、式を新しい値で新しい式に置き換える必要があります。

あなたのリストは、Etern_Funcによって作成された時点で提供された値で実行される式のリストであるため、ほとんどの場合、あなたが求めているものを最もよく見積もることができます。

1

クロージャは、値ではなく変数をキャプチャします。それが明確であることを確認してください。

var1,およびvar3は、ローカルでのみ変更できる値の引数で渡されます。したがって、あなたが内にそれらを変更しない場合Extern_Funcあなたは行くのが良いです。

次のスニペットを検討し、キャプチャ値や変数間の違いを理解するには、次の

var funcs = new List<Action>(); 

for (var i = 0; i < 5; i++) 
{ 
    var temp = i; 
    funcs.Add(() => Console.WriteLine(i)); 
    funcs.Add(() => Console.WriteLine(temp)); 
} 

foreach (var f in funcs) 
{ 
    f(); 
} 

は、あなたが出力を推測することはできますか?

関連する問題