最近要因为要使用到多线程,经常要把一些方法封起来,给线程去执行,刚开始的时候,根据自己之前学的C#知识,去创建一些委托,然后把方法作为参数传递给其中一个方法的线程去执行,每次都要new一些委托,实在是烦,其实知道有一些简便的方法去做的(比如使用Action和匿名方法以及lambda 表达式),但本人有点懒,本想能自己自定义 委托就自定义委托去实现呗,最后由于越来越多这样情况出现,就干脆好好去看看Action和匿名方法以及lambda 表达式,怎么才能更方便的去实现方法的传递!废话不多说,先逐一温习一下概念,讲解过程中,有错误欢迎指出!
Action 委托:
概念:封装一个方法,该方法不具有参数并且不返回值。
可以使用此委托以参数形式传递方法,而不用显式声明自定义的委托。 封装的方法必须与此委托定义的方法签名相对应。 也就是说,封装的方法不得具有参数,并且不得返回值,说简浅一点就是,当你需要去定义一个不需要参数并且不需要返回值的委托时,微软不用我们去自己去定义,可以用Action代替你定义的委托(如果你需要传递参数可以用Action<T>,如果你需要参数也需要返回值可以用Func<T,TResult>,大家可以自己去了解一下! ).
平常我们要使用委托的时候,需要自定义委托,然后把符合的方法赋值给委托,让委托去执行,例如以下代码显式声明了一个名为 ShowValue 的委托,并将对 Name.DisplayToWindow 实例方法的引用分配给其委托实例:
using System; using System.Windows.Forms; public delegate void ShowValue(); public class Name { private string instanceName; public Name(string name) { this.instanceName = name; } public void DisplayToConsole() { Console.WriteLine(this.instanceName); } public void DisplayToWindow() { MessageBox.Show(this.instanceName); } } public class testTestDelegate { public static void Main() { Name testName = new Name("Koani"); ShowValue showMethod = testName.DisplayToWindow; showMethod(); } }
这是平常我们自定义委托去执行一个方法,这样虽然清晰明了,但是却是麻烦,每次都得根据方法签名去自定义一些委托,增加代码系统开销啊,写多了也累!那
用Action看看,方便点不!
下面请看一个使用Action的例子,简化了此代码,它所用的方法是实例化 Action 委托,而不是显式定义一个新委托并将命名方法分配给该委托!
using System; using System.Windows.Forms; public class Name { private string instanceName; public Name(string name) { this.instanceName = name; } public void DisplayToConsole() { Console.WriteLine(this.instanceName); } public void DisplayToWindow() { MessageBox.Show(this.instanceName); } } public class testTestDelegate { public static void Main() { Name testName = new Name("Koani"); Action showMethod = testName.DisplayToWindow; showMethod(); } }
有了action之后直接上,省得去自定义委托了,方便了许多,明白action的好处了吧!
匿名方法:
概念:匿名方法,顾名思义就是没有名称的方法!
在 2.0 之前的 C# 版本中,声明委托的唯一方法是使用命名方法。 C# 2.0 引入了匿名方法,主要是您可使用匿名方法来忽略参数列表。这意味着匿名方法可转换为具有各种签名的委托,通过使用匿名方法,由于您不必创建单独的方法,因此减少了实例化委托所需的编码系统开销!
要将代码块传递为委托参数,创建匿名方法则是唯一的方法!请看下面示例:
//示例1,用匿名方法直接传递给按钮的点击事件去执行,不用去实例一个方法了 button1.Click += delegate(System.Object o, System.EventArgs e) { System.Windows.Forms.MessageBox.Show("Click!"); }; //示例2,直接将匿名方法赋给委托,当然你也可以用上面我说的Action去接收匿名方法,这里只是为了方便去说明 delegate void Del(int x); Del d = delegate(int k) { /* ... */ };
有了匿名方法,是不是方便点了,要执行什么代码,直接用匿名方法去封装,不用去实例一个新的方法,这种用法,在多线程下使用起来更加方便,例如:
void StartThread() { System.Threading.Thread t1 = new System.Threading.Thread (delegate() { System.Console.Write("Hello, "); System.Console.WriteLine("World!"); }); t1.Start(); }
如果创建方法所需的系统开销是不必要的,则指定代码块(而不是委托)可能非常有用。 启动新线程即是一个很好的示例。 无需为委托创建更多方法,线程类即可创建一个线程并且包含该线程执行的代码。上示例,里面线程的参数是一个无参数的委托(类似action),所以直接传递无参数的匿名方法进去就行了!无需自己再去定义委托之类!
Lambda 表达式:
看官方对lambda表达式的解析!
Lambda 表达式是一种可用于创建委托或表达式目录树类型的匿名函数。 通过使用 lambda 表达式,可以写入可作为参数传递或作为函数调用值返回的本地函数。 Lambda 表达式对于编写 LINQ 查询表达式特别有用。
是不是,看着一头雾水,不错,我也是,官方的东西总是文绉绉的,简单来说简化了匿名函数的使用,让你让代码更加简洁,优雅,用运算符 " => "表示,左边指定输入
参数,右边是lambda的主体!
lambda表达式:
1.一个参数:param=>expr
看示例:
delegate int del(int i); static void Main(string[] args) { del myDelegate = x => x * x; int j = myDelegate(5); //j = 25 }
这是lambda表达式的表示,注意:只有一个输入参数时,括号才是可选的;否则括号是必需的。 括号内的两个或更多输入参数使用逗号加以分隔。
2.多个参数:(param-list)=>expr
//示例1 (x, y) => x == y //示例2 (x,y,z) => SomeMethod();
lambda表达式也是可以和action结合进行使用,例如:
using System; using System.Windows.Forms; public class Name { private string instanceName; public Name(string name) { this.instanceName = name; } public void DisplayToConsole() { Console.WriteLine(this.instanceName); } public void DisplayToWindow() { MessageBox.Show(this.instanceName); } } public class LambdaExpression { public static void Main() { Name testName = new Name("Koani"); //此处是lambda表达式和action结合 Action showMethod = () => testName.DisplayToWindow(); showMethod(); } }
Lambda 的一般规则如下:
-
Lambda 包含的参数数量必须与委托类型包含的参数数量相同。
-
Lambda 中的每个输入参数必须都能够隐式转换为其对应的委托参数。
-
Lambda 的返回值(如果有)必须能够隐式转换为委托的返回类型。
(有问题,大家多少交流836911886,加我请记得说:博客园)