关于Action 委托和匿名方法以及lambda 表达式的一些理解

  最近要因为要使用到多线程,经常要把一些方法封起来,给线程去执行,刚开始的时候,根据自己之前学的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,加我请记得说:博客园)

 

posted @ 2014-07-07 12:18  技术_菜鸟  阅读(8739)  评论(0编辑  收藏  举报