このコードは動作するはずです:
public MyClass()
{
Int64 po = 123456;
foreach (Expense expense in pr.Expenses)
{
var expenseName = expense.ExpenseName;
Button btnExpenseDetail = new Button();
btnExpenseDetail.Text = expense.ExpenseName;
btnExpenseDetail.Location = new Point(startLocation.X + 410, startLocation.Y + (23 *
btnExpenseDetail.Click += (sender, e) => { MyHandler(sender, e, po, expenseName); };
pnlProjectSummary_Expenses.Controls.Add(btnExpenseDetail);
}
}
void MyHandler(object sender, EventArgs e, string po, string category)
{
FormExpenseDetails ed = new FormExpenseDetails(po, category);
ed.Show();
}
は、より基本的なものの上に行くことができます。
static void Main(string[] args)
{
var qs = new List<Action>();
for (var i = 0; i < 10; i++)
qs.Add(() => f("doer", i));
for (var i = 0; i < 10; i++)
qs[i]();
}
private static void f(string x, int y)
{
Console.WriteLine("{0}: {1}", x, y);
}
上記のコードを実行すると、出力は常に "doer:10"と表示されます。そのコード逆コンパイルすることができます:
private static void f(string x, int y)
{
Console.WriteLine("{0}: {1}", x, y);
}
private static void Main(string[] args)
{
List<Action> qs = new List<Action>();
<>c__DisplayClass1 CS$<>8__locals2 = new <>c__DisplayClass1();
CS$<>8__locals2.i = 0;
while (CS$<>8__locals2.i < 10)
{
qs.Add(new Action(CS$<>8__locals2.<Main>b__0));
CS$<>8__locals2.i++;
}
for (int i = 0; i < 10; i++)
{
qs[i]();
}
}
[CompilerGenerated]
private sealed class <>c__DisplayClass1
{
// Fields
public int i;
// Methods
public void <Main>b__0()
{
Program.f("doer", this.i);
}
}
あなたが見ることができるように、コンパイラがc__DisplayClass1
という名前のクラスを生成し、ループに入る前に一度初期化されました。その後、変数CS$<>8__locals2
のi
プロパティをインクリメントしただけです。
私は次のループにtheeseラムダを呼び出すときに、それは内部変数を見てCS$<>8__locals2
オブジェクトを使用しています。
(私の英語は、それを説明するのは良いenaughではありませんが、それはすべてあります...)
「のC#」などを使用してタイトルを接頭辞ないでください。それがタグのためのものです。 –