2017-01-12 42 views
1

渡された整数に基づいてロジックを実行できるように、整数値をElapsedEventHandlerに渡そうとしています。しかし、イベントが発生すると、値はIではありませんに初期化しました。私は、代表者の仕組みを完全に理解していないかもしれません。ElapsedEventHandlerに引数を渡す方法

class Example 
{ 
    Dictionary<int, Timer> timer; 

    public Example() 
    { 
     timer = new Dictionary<int, timer>(); 
     for(int i = 0; i < 12; ++i) 
     { 
      timer.Add(i, new Timer(5000)); 
      timer[i].Elapsed += delegate { TimerTickCustom(i); }; 
     } 
    } 
    public void Process() // called each cycle 
    { 
     for(int i = 0; i < 12; ++i) 
     { 
      timer[i].Start(); 
     } 
    } 
    private void TimerTickCustom(int i) 
    { 
     // The value of i coming in does not match the dictionary key. 
    } 
} 
+1

「タイマー」を拡張してそこにフィールドを作成する新しいオブジェクトを作ってみてください! – Ilan321

+0

私はまだその時点でデリゲートを使用していますか? – user2970916

+0

@ Ilan321 'tick'ハンドラでデータを使用するたびに、新しいタイマーを作成する必要はありません。それは概念的な意味を持たない(それは別の種類のタイマーではない)より多くの作業であり、単に不必要である。 – Servy

答えて

1

これは、デリゲートは、それのスコープに「特異的」とみなしするためのローカル値iがどこにあるかに依存します。 iがループの外で定義されているため、代理人は、この変数の自身の "コピー"を定義していません。すべての代理人は同じものを期待しています。i

代理人自身と同じレベルの変数に代入する必要があります。

ここで正しい言語を使用しているかどうかはわかりません。しかし、これは動作するはずです:あなたは(誰かがあなたに告げるまではもちろん、あなたが本当に知ることができません)検索エンジンに入力した言葉を知っていれば

class Example 
{ 
    Dictionary<int, Timer> timer; 

    public Example() 
    { 
     timer = new Dictionary<int, Timer>(); 
     for(int i = 0; i < 12; ++i) 
     { 
      int iInScopeOfDelegate = i; 
      timer.Add(i, new Timer(5000)); 
      timer[i].Elapsed += delegate { TimerTickCustom(iLocalToDelegate); }; 
     } 
    } 
    public void Process() // called each cycle 
    { 
     for(int i = 0; i < 12; ++i) 
     { 
      timer[i].Start(); 
     } 
    } 
    private void TimerTickCustom(int i) 
    { 
     // The value of i coming in does not match the dictionary key. 
    } 
} 

をいくつかinteresting discussionがあります。

関連する問題