一連のデリゲートアクションを使用して一連のイベントを割り当てようとしたときに、この問題が発生しました。この関数を使用するとAssignEventsManually()
、イベントによって、割り当てられたデリゲートが、含まれている情報(異なる番号)で正しくトリガーされます。ループを使用してこれらの割り当てを行うと、すべてのボタンが同じ値「B2」を出力します。
デリゲート自体はヒープに格納されているようですが、反復番号i
はスタックにあり、各デリゲートは同じアイテムを参照しています。各デリゲートにイテレータの独自のインスタンスを割り当てるにはどうすればよいですか?
using System.Windows.Forms;
namespace DelegatesTest
{
public partial class Form1 : Form
{
Button[] bar;
public Form1()
{
InitializeComponent();
bar = new Button[] { button1, button2, button3 };
for (int i=0; i<3; i++)
{
bar[i].Click += delegate
{
richTextBox1.Text = $"B{i}";
};
}
//AssignEventsManually();
}
void AssignEventsManually()
{
button1.Click += delegate
{
richTextBox1.Text = $"b{1}";
};
button2.Click += delegate
{
richTextBox1.Text = $"b{2}";
};
button3.Click += delegate
{
richTextBox1.Text = $"b{3}";
};
}
}
}
デリゲート自体はヒープに格納されているようですが、反復番号「i」がスタックにあり、各デリゲートは同じアイテムを参照しています。各デリゲートにイテレータの独自のインスタンスを割り当てるにはどうすればよいですか?
i
これは、コンテキストクラスのヒープ上にある「キャプチャされた」変数です。コンテキストクラスのスコープは、と同じi
です。つまり、ループの期間中です。
これを修正するには:ループi
内のスナップショットコピーを作成します。
for (int i=0; i<3; i++)
{
int cpy = i;
bar[i].Click += delegate
{
richTextBox1.Text = $"B{cpy}";
};
}
またはおそらくより効率的に:
for (int i=0; i<3; i++)
{
string txt = $"B{i}";
bar[i].Click += delegate
{
richTextBox1.Text = txt;
};
}
余分なローカルの範囲があるので、これは動作します内側ループので、:ループの繰り返しごとに異なる捕捉コンテキストを。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加