我刚开始没有掌握匿名方法这些就是按照下面这些写的,说实话很痛苦。后来接触了匿名表达式,lambda后几乎都不想再想写这样的东西了,除非特殊的一些情况,比如需要自己定义委托。如果您现在还在按照下面这样写,那么这篇文章对你或许有些帮助!
//声明一个委托 delegate void UpdateProgressDelegate(); //声明一个UpdateProgressDelegate的委托实例 private UpdateProgressDelegate UpdateProgressHandle; public Form1() { InitializeComponent(); progressBar1.Maximum = 100; progressBar1.Minimum = 0; progressBar1.Value = 0; //将该委托实例和UpdateProgressValue方法绑定起来 UpdateProgressHandle = new UpdateProgressDelegate(UpdateProgressValue); } private void button1_Click(object sender, EventArgs e) { Thread t = new Thread(new ThreadStart(D)); t.Start(); } private void D() { //其他事情 //.......... progressBar1.Invoke(UpdateProgressHandle); //调用Invoke更新进度条,参数是我们新建的委托 } //更新进度条的方法 private void UpdateProgressValue() { for (int i = 0; i < 50; i++) { progressBar1.Value = i; } }
这个写法基本就是.net 1.x里面的委托写法了。您也看出来,很繁琐。像一个多线程的界面中,要和多线程打交道的控件何止一个两个。几个一来就会感觉很烦了。维护起来也不方便。 下面我们使用.net 2.0中的一个新特性:支持省略委托的创建,直接将方法名字赋给需要的参数。即我们可以将
Thread t = new Thread(new ThreadStart(D));
改为:
Thread t = new Thread(D);
虽然只是少了一点,不过好歹也是个进步对吧。
现在我们引入.net 2.0中的匿名委托来改善下上面这个程序,使其看起来更加简洁点。怎样使用匿名委托?教你个简单的方法,程序中参数是方法名字的地方您都可以通过delegate(){//操作}的形式来代换。比如下面我们就像D方法名那里给替换掉。
//声明一个委托 delegate void UpdateProgressDelegate(); //声明一个UpdateProgressDelegate的委托实例 private UpdateProgressDelegate UpdateProgressHandle; public Form1() { InitializeComponent(); progressBar1.Maximum = 100; progressBar1.Minimum = 0; progressBar1.Value = 0; //将该委托实例和UpdateProgressValue方法绑定起来 UpdateProgressHandle = new UpdateProgressDelegate(UpdateProgressValue); } private void button1_Click(object sender, EventArgs e) { Thread t = new Thread(delegate() { progressBar1.Invoke(UpdateProgressHandle); }); t.Start(); } //更新进度条的方法 private void UpdateProgressValue() { for (int i = 0; i < 50; i++) { progressBar1.Value = i; } }
public partial class Form1 : Form { public Form1() { InitializeComponent(); progressBar1.Maximum = 100; progressBar1.Minimum = 0; progressBar1.Value = 0; } private void button1_Click(object sender, EventArgs e) { Thread t = new Thread(delegate() { progressBar1.Invoke(new Action(UpdateProgressValue)); }); t.Start(); } //更新进度条的方法 private void UpdateProgressValue() { for (int i = 0; i < 50; i++) { progressBar1.Value = i; } } }
可以看到我们之前声明的那一长段的委托都去掉了,清爽了不少。那么在.net 2中该如何使用呢?两个办法:
1.强制在UpdateProgressValue中加个参数,但我们不使用。代码如下:
public Form1()
{
InitializeComponent();
progressBar1.Maximum = 100;
progressBar1.Minimum = 0;
progressBar1.Value = 0;
}
private void button1_Click(object sender, EventArgs e)
{
Thread t = new Thread(delegate() { progressBar1.Invoke(new Action<int>(UpdateProgressValue),0); });
t.Start();
}
//更新进度条的方法
private void UpdateProgressValue(int x)
{ for (int i = 0; i < 50; i++)
{
progressBar1.Value = i;
}
}
2.不使用Action委托,还记得我们最朴素写法中的ThreadStart这个委托吗?这个就是一个现成的无参数委托,不用白不用!代码如下:
public Form1()
{
InitializeComponent();
progressBar1.Maximum = 100;
progressBar1.Minimum = 0;
progressBar1.Value = 0;
}
private void button1_Click(object sender, EventArgs e)
{
Thread t = new Thread(delegate() { progressBar1.Invoke(new ThreadStart(UpdateProgressValue)); });
t.Start();
}
//更新进度条的方法
private void UpdateProgressValue()
{ for (int i = 0; i < 50; i++)
{
progressBar1.Value = i;
}
}
上面我们已经说过了,有方法名为参数的地方可以使用匿名方法替代,那么上面的那个new Action(UpdateProgressValue)中的UpdateProgressValue我们同样可以再给替换掉了。代码如下:
public Form1()
{
InitializeComponent();
progressBar1.Maximum = 100;
progressBar1.Minimum = 0;
progressBar1.Value = 0;
}
private void button1_Click(object sender, EventArgs e)
{
Thread t = new Thread(delegate()
{
progressBar1.Invoke(new Action(delegate()
{ for (int i = 0; i < 50; i++)
{
progressBar1.Value = i;
}
}));
});
t.Start();
}
我们最后引入lambda来简化我们的代码。Lambda表达式在C#中的写法是“arg-list => expr-body”,“=& gt;”符号左边为表达式的参数列表,右边则是表达式体(body)。参数列表可以包含0到多个参数,参数之间使用逗号分割。当然因为我们这里没有参数所 有可以直接写成()=>{}的形式了啦。lambda用在哪里呢?它可以替换匿名表达式使其更加简单,在LINQ等等查询语句中也有使用,不过不是 我们今天讨论的范围。如何替换匿名表达式呢?代码如下:
private void button1_Click(object sender, EventArgs e) { Thread t = new Thread(() => progressBar1.Invoke(new Action(()=> { for (int i = 0; i < 50; i++) { progressBar1.Value = i; } }))); t.Start(); }
可以看到使用了lambda后匿名方法中的一些不需要的{}被省略了,自然看起来也就爽多啦。如果非要总结一个怎么替换的过程的话那就简单的认为将delegate(){}替换为了()=>{},如果有参数类似。
http://www.cnblogs.com/tiwlin/archive/2011/03/23/1992230.html
----------------------------------------------------------------------------------------------------------------------------------------
匿名委托——为事件(event)注册匿名委托
// Create a handler for a click event.
button1.Click += delegate(System.Object o, System.EventArgs e)
{
System.Windows.Forms.MessageBox.Show("Click!");
};
注册方法注意事项:
1. += 操作符后 无 new 关键字
2. 如需要 为 Click 注册匿名委托,则在 Click 上按 F12 查看事件的声明
3. 定位到该事件声明时使用的代理,定位后再在代理上 按F12 查看代理的声明
4. 将代理的形参列表复制下来
5.这是就可以写匿名方法了,如下
button1.Click += delegate(黏贴你复制的形参列表)
{
// 逻辑代码段
};
还有一种事件注册方法:就是使用 匿名函数 Action 或者 Fun 注册的事件处理函数,如下
public void test1()
{
Action OnEvent =(()={
//事件处理函数
});
MyClass mc = new MyClass();
mc.MyEvent += OnEvent; // 使用匿名方法注册这个事件
mc.MyFun(); // 当然这个方法会调用 MyEvent 事件
mc.MyEvent -= OnEvent; //这个很重要,记得要卸载事件哦!!!!!!
}
特别提示:一定记得自己注册的事件在逻辑结束后,要卸载已经注册的事件。否则会死的非常惨!!