UserControl uc = new UserControl();
int len = 1024 * 10;
uc.Size = new System.Drawing.Size(len, len);
for (int i = 0; i < 50; i++)
{
    Button button = new Button();
//button里面的文字是正确的
    button.Text = "Test"+i;
    button.Top = i *32;
    button.Click += (o1, e1) =>
    {
//点击每个按钮后都显示的都是Test50,怎么不是对应的序列?
        MessageBox.Show("Test" + i);
    };    uc.Controls.Add(button); 
}
ActionsPane.Controls.Add(uc);

解决方案 »

  1.   

    i是click事件时的i,click的时候i已经等于50了,
      

  2.   

    i在匿名委托中会被视为一个变量,i仍然是for循环中的变量i,click的时候,会访问for循环的变量i,
      

  3.   

    这跟lambda公式没关系。
    你虽然循环了50次之多,但是button的位置都没有改变, 也就是说在一个位置上叠加了50个button。
    只不过你看上去只有1个
    当你点这个button的时候,时间上是调用了最后一个button的click事件。打印出来。当然是Test50了
      

  4.   

    lambda表达式在哪儿呢?木有看到..........
      

  5.   

    MessageBox.Show((o1 as Button).Text);
      

  6.   

    有个现象你没法解释,i其实是从0到49,50的时候已经退出循环,如果叠加的话,显示的应该是Test49,而不是Test50,
      

  7.   

    UserControl uc = new UserControl();
    int len = 1024 * 10;
    uc.Size = new System.Drawing.Size(len, len);
    for (int i = 0; i < 50; i++)
    {
        Button button = new Button();
    //button里面的文字是正确的
        button.Text = "Test"+i;
        button.Top = i *32;
        button.Tag=("Test" + i);
        button.Click += (o1, e1) =>
        {
    //点击每个按钮后都显示的都是Test50,怎么不是对应的序列?
            MessageBox.Show((o1 as Button).Tag as string);
        };    uc.Controls.Add(button); 
    }
    ActionsPane.Controls.Add(uc);
      

  8.   

    button.Top = i *32;
    显示了50个button。
      

  9.   

    有点弄不懂,怎么在lambda使用的i都变成50,而不对应的值。
      

  10.   

                UserControl uc = new UserControl();
                int len = 1024 * 10;
                uc.Size = new System.Drawing.Size(len, len);
                for (int i = 0; i < 50; i++)
                {
                    Button button = new Button();
                    button.Text = "Test" + i;
                    button.Top = i * 32;
                    button.Tag = i;
                    button.Click += (o1, e1) =>
                    {
                        MessageBox.Show("Test" + button.Tag);
                    };
                    uc.Controls.Add(button);
                }
                panel1.Controls.Add(uc);
      

  11.   

    不过不是有点不明白,每次循环都用的是不同i值,怎么最后都变成了50?
    UserControl uc = new UserControl();
    int len = 1024 * 10;
    uc.Size = new System.Drawing.Size(len, len);
    for (int i = 0; i <50; i++)
    {
        Button button = new Button();
        button.Text = "Test"+i;
        button.Top = i *32;
        //这样也正确
        int j = i;
        button.Click += (o1, e1) =>
        {
            MessageBox.Show("Test" + j);
        };
        uc.Controls.Add(button); 
    }
    ActionsPane.Controls.Add(uc);
      

  12.   


    很简单,lambda定义了一个匿名委托,实际上是一个方法,调用这个方法的时候,也就是按下按钮时,i已经等于50了,按下按钮时for循环已经退出,这时候i=50,如果你多事,在循环后加上一句i=10000;你会发现显示的是Test10000,
      

  13.   

    {
    //点击每个按钮后都显示的都是Test50,怎么不是对应的序列?
            MessageBox.Show("Test" + i);
        };
    这段代码相当于一个方法,此方法并不是每次循环都要执行的,而是每次触发click事件时才执行,所以循环中i是多少都没有意义,只有点击按钮时的i值才有效,点击时已经在49的基础上i++了,当然都是50
      

  14.   


    // TO: stonespace
    // 我觉得 i 已经等于 50 的这个说法不准确,为什么?因为当 for 循环结束的时候,i 的值已经丢弃了,
    // 当每次点击的时候,根本取的不是 i 的值。因为这个时候已经没有 i 了。
    // 但事件中又确确实实是绑定了 i 的值,经过分析我觉得原因如下:// 在 Lamdha Expression 出现以前,要绑定事件必须先定义一个和事件具有相同签名的函数
    // 就像这样:
    private void ButtonClick(object sender, EventArgs e)
    {
        ......
    }// 楼主程序中出现了 i,也就是说在 ButtonClick 方法内部使用了 i,而通过方法的签名可以得知,
    // 入参并没有 i,这个 i 是哪来的,他如何才能进入 ButtonClick 方法内部?
    // 很明显,Lamdha 在内部实现的时候使用了类似于全局变量的实现方式,也就是说,
    // 在方法外面,定义全局实例变量,假设叫 I,
    // 只有通过这样,方法才能访问外部的变量,否则怎么访问?Lamdha 本质上也只是简化操作而已。// 所以,以上 Lamdha 绑定部分可以等价于下面这样:
    I = i;
    btn.Click += ButtonClick;
    // 而在 ButtonClick 内部的实现则可以是:
    MessageBox.Show("Test" + I.ToString());// 很明显,当点击按钮触发事件的时候,取得的是 I 的值。// 而且还有一点,在循环退出去之后,i 还做了一次自增,而这时也确实显示的是 50。
    // 我觉得微软内部在实现的方式上对 i 的变量的改变进行了监听。所以当每次 i 的值改变,
    // I 的值也会重新复制,总的来说,
    // 我们可以用以下替换代码来解释上述原因:
    private int I = 0;private void button1_Click(object sender, EventArgs e)
    {
        for (int i = 0; i < 10; i++)
        {
            Button btn = new Button();
            btn.Name = "Button" + i;
            btn.Text = (i + 1).ToString();
            btn.Location = new Point((i % 3) * btn.Width, (i / 3) * btn.Height);
            I = i;
            btn.Click += ButtonClick;
            panel1.Controls.Add(btn);
        }    I++;
    }
    private void ButtonClick(object sender, EventArgs e)
    {
        MessageBox.Show(I.ToString());
    }
      

  15.   

    又试了一下:
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    namespace Test5
    {
        class Program
        {
            static void Main(string[] args)
            {
                for (int i = 0; i < 100; i++)
                {
                    Button button = new Button();
                    button.Click += (obj, e) =>
                    {
                        MessageBox.Show(i.ToString());
                    };
                }
            }
        }
    }
      

  16.   

    文明点好不好,不要骂人,我草*泥*马IL代码:
    .method private hidebysig static void  Main(string[] args) cil managed
    {
      .entrypoint
      // 代码大小       81 (0x51)
      .maxstack  4
      .locals init ([0] class [System.Windows.Forms]System.Windows.Forms.Button button,
               [1] class [mscorlib]System.EventHandler 'CS$<>9__CachedAnonymousMethodDelegate1',
               [2] class Test5.Program/'<>c__DisplayClass2' 'CS$<>8__locals3',
               [3] bool CS$4$0000)
      IL_0000:  nop
      IL_0001:  ldnull
      IL_0002:  stloc.1
      IL_0003:  newobj     instance void Test5.Program/'<>c__DisplayClass2'::.ctor()
      IL_0008:  stloc.2
      IL_0009:  ldloc.2
      IL_000a:  ldc.i4.0
      IL_000b:  stfld      int32 Test5.Program/'<>c__DisplayClass2'::i
      IL_0010:  br.s       IL_0042
      IL_0012:  nop
      IL_0013:  newobj     instance void [System.Windows.Forms]System.Windows.Forms.Button::.ctor()
      IL_0018:  stloc.0
      IL_0019:  ldloc.0
      IL_001a:  ldloc.1
      IL_001b:  brtrue.s   IL_002c
      IL_001d:  ldloc.2
      IL_001e:  ldftn      instance void Test5.Program/'<>c__DisplayClass2'::'<Main>b__0'(object,
                                                                                          class [mscorlib]System.EventArgs)
      IL_0024:  newobj     instance void [mscorlib]System.EventHandler::.ctor(object,
                                                                              native int)
      IL_0029:  stloc.1
      IL_002a:  br.s       IL_002c
      IL_002c:  ldloc.1
      IL_002d:  callvirt   instance void [System.Windows.Forms]System.Windows.Forms.Control::add_Click(class [mscorlib]System.EventHandler)
      IL_0032:  nop
      IL_0033:  nop
      IL_0034:  ldloc.2
      IL_0035:  dup
      IL_0036:  ldfld      int32 Test5.Program/'<>c__DisplayClass2'::i
      IL_003b:  ldc.i4.1
      IL_003c:  add
      IL_003d:  stfld      int32 Test5.Program/'<>c__DisplayClass2'::i
      IL_0042:  ldloc.2
      IL_0043:  ldfld      int32 Test5.Program/'<>c__DisplayClass2'::i
      IL_0048:  ldc.i4.s   100
      IL_004a:  clt
      IL_004c:  stloc.3
      IL_004d:  ldloc.3
      IL_004e:  brtrue.s   IL_0012
      IL_0050:  ret
    } // end of method Program::Main
      

  17.   

    你还是比较专业,你好像说对了:
    lambda新建了一个Test5.Program/'<>c__DisplayClass2',用的是
    Test5.Program/'<>c__DisplayClass2'::i