原文:匿名方法,Lambda表达式,高阶函数

  • 匿名方法

c#2.0引入匿名方法,不必创建单独的方法,因此减少了所需的编码系统开销。 常用于将委托和匿名方法关联,例如

1. 使用委托和方法关联:

this.btnRefresh.Click += new System.EventHandler(this.btnRefresh_Click);private void btnRefresh_Click(object sender, EventArgs e){    BindData();}

2. 使用委托和匿名方法关联:
this.btnRefresh.Click +=  delegate(object sender, EventArgs e) { BindData(); };

毫无疑问,如果关联的方法是“一句话方法”的话,代码2更为简洁(实际上编译器在背后为我们创建了类似btnRefresh_Click的方法)。

  • 匿名方法省略参数列表

定义匿名方法时候,参数列表是可以省略的,编译器可以根据委托的签名来确定函数的签名。例如,
delegate void Func(int x);
//带参数
Func f1= delegate (int p) { Console.Write(p); }
// 不带参数
Func f2 = delegate { Console.Write("he");} //编译器自动推断函数签名带int参数
使用不带参数的匿名方法,注意问题
   一是因为没有参数,所以在方法内就不能使用参数。
    二是有些情况不能使用匿名方法,有ambiguous的问题,例如
public Thread(ParameterizedThreadStart start);
public Thread(ThreadStart start);
而// public delegate void ParameterizedThreadStart(object obj);
   // public delegate void ThreadStart();
所以使用
Thread thread = new Thread(
                delegate { sh.LockMyself(); }
            );
就会有问题
Error  The call is ambiguous between the following methods or properties: 'System.Threading.Thread.Thread(System.Threading.ThreadStart)' and 'System.Threading.Thread.Thread(System.Threading.ParameterizedThreadStart)' 

编译器不知道应该将delegate { }这一匿名方法还原为哪个函数,解决方法是显式给定参数列表,让编译器知道你要用那个函数:
Thread thread = new Thread(
                delegate() { sh.LockMyself(); }
            );

Lambda表达式:
Thread thread = new Thread(
           () => 
           {
                sh.LockMyself();
            }
           );

  • Lambda表达式

Lambda表达式为编写匿名方法提供了更简明的函数式的句法,但结果却在编写LINQ查询表达式时变得极其有用,因为它们提供了一个非常紧凑的而且类安全的方式来编写可以当作参数来传递,在以后作运算的函数。
Lambda 表达式和 匿名方法 其实是一件事情。唯一的不同是:他们语法表现形式不同。Lambda 表达式是在语法方面的更进一步的进化。在本质上,他们是一件事情。他们的作用都是:产生方法。即:内联方法。

books是System.Collections.Generic.List类型, 即List<Book>, 有Find方法
使用匿名方法:              books.Find(delegate(Book book){return book.Price < 50;});
使用Lambda表达式:      books.Find(book=>book.Price<50);
book是输入参数; =>读作Go to,是Lambda操作符;book.Price<50是表达式或者语句块。
Lambda表达式中的输入参数省略参数类型,因为当前Find扩展方法对象是books,编译器会自动推断book参数属于BooK类型.
对比另一个例子:

// 使用匿名方法string[] list = new string[] { "abc", "12", "java" }; string[] alist = Array.FindAll(list,                       delegate(string s)                       {                          return s.IndexOf("a") >= 0;                       }                  ); foreach (string var in alist) { Console.WriteLine(var); } // 使用Lambda表达式string[] list = new string[] { "abc", "12", "java" }; string[] alist = Array.FindAll(list, s => (s.IndexOf("a") >= 0)); 

Lambda表达式式范例:

//x的类型省略了,编译器可以根据上下文推断出来,后面跟着的是表达式x => x+1 deleage(int x){return x+1;}//后面跟着的是语句块x=>{return x+1;}delegate(int x){return x+1;}//输入参数也可以带类型,带类型后别忘记小括号哦(int x) => x+1delegate(int x){return x+1;}//也可以多个输入参数,逗号分隔,别忘记小括号(x,y) => x+ydelegate(int x,int y){return x+y;}//无参的也行() => 1delegate(){return 1;} 

高阶函数(higher-order function)

是指把另一个函数作为参数或返回值的函数。
例如在System.Array类中就有许多静态的高阶函数,其中的ConvertAll方法可谓是最常用的高阶函数之一了:

private static DateTime StringToDateTime(string s) { return DateTime.ParseExact(s, "yyyy-MM-dd", null);}static void Main(string[] args) { string[] dateStrings = new string[] { "2009-01-01", "2009-01-02", "2009-01-03", "2009-01-04", "2009-01-05", "2009-01-06", }; // ConvertAll将一个数组映射为另一个数组, new Converter是构建一个委托对象 // 类似于 new System.EventHandler(this.btnRefresh_Click); DateTime[] dates = Array.ConvertAll<string, DateTime>( dateStrings, new Converter<string, DateTime>(StringToDateTime));}// C# 2.0中,又引入了匿名方法这一构建委托对象的方式:DateTime[] dates = Array.ConvertAll<string, DateTime>( dateStrings, delegate(string s) { return DateTime.ParseExact(s, "yyyy-MM-dd", null); });// 新增了Lambda表达式和扩展方法等语言特性,再加上范型类型的自动判断,在C# 3.0中使用匿名方法更是异常简洁,甚至与ruby的语法如出一辙IEnumerable<DateTime> dates = dateStrings.Select( s => DateTime.ParseExact(s, "yyyy-MM-dd", null));

Reference
http://blog.csdn.net/shouyenet1/archive/2009/04/28/4133114.aspx
http://blog.joycode.com/scottgu/archive/2007/04/09/100744.aspx
http://www.infoq.com/cn/articles/higher-order-function
http://www.infoq.com/cn/articles/higher-order-function
 

匿名方法,Lambda表达式,高阶函数的更多相关文章

  1. C# delegate event func action 匿名方法 lambda表达式

    delegate event action func 匿名方法 lambda表达式 delegate类似c++的函数指针,但是是类型安全的,可以指向多个函数, public delegate void ...

  2. 18、(番外)匿名方法+lambda表达式

    概念了解: 1.什么是匿名委托(匿名方法的简单介绍.为什么要用匿名方法) 2.匿名方法的[拉姆达表达式]方法定义 3.匿名方法的调用(匿名方法的参数传递.使用过程中需要注意什么) 什么是匿名方法? 匿 ...

  3. 匿名函数 =匿名方法+ lambda 表达式

    匿名函数的定义和用途 匿名函数是一个"内联"语句或表达式,可在需要委托类型的任何地方使用. 可以使用匿名函数来初始化命名委托[无需取名字的委托],或传递命名委托(而不是命名委托类型 ...

  4. 委托-异步调用-泛型委托-匿名方法-Lambda表达式-事件【转】

    1. 委托 From: http://www.cnblogs.com/daxnet/archive/2008/11/08/1687014.html 类是对象的抽象,而委托则可以看成是函数的抽象.一个委 ...

  5. C#多线程+委托+匿名方法+Lambda表达式

    线程 下面是百度写的: 定义英文:Thread每个正在系统上运行的程序都是一个进程.每个进程包含一到多个线程.进程也可能是整个程序或者是部分程序的动态执行.线程是一组指令的集合,或者是程序的特殊段,它 ...

  6. C#委托总结-匿名方法&Lambda表达式

    1,匿名方法 匿名方法可以在声明委托变量时初始化表达式,语法如下 之前写过这么一段代码: delegate void MyDel(string value); class Program { void ...

  7. 委托delegate 泛型委托action<> 返回值泛型委托Func<> 匿名方法 lambda表达式 的理解

    1.使用简单委托 namespace 简单委托 { class Program { //委托方法签名 delegate void MyBookDel(int a); //定义委托 static MyB ...

  8. Scala高阶函数

    1.作为参数的函数 函数可以作为一个参数传入到一个方法当中去 def main(args: Array[String]): Unit = { val myFunc1 =(x:Int) =>{ x ...

  9. Kotlin高阶函数实战

    前言 1. 高阶函数有多重要? 高阶函数,在 Kotlin 里有着举足轻重的地位.它是 Kotlin 函数式编程的基石,它是各种框架的关键元素,比如:协程,Jetpack Compose,Gradle ...

随机推荐

  1. iOS学习——JSON数据解析(十一)

    在之前的<iOS学习——xml数据解析(九)>介绍了xml数据解析,这一篇简单介绍一下Json数据解析.JSON 即 JavaScript Object Natation,它是一种轻量级的 ...

  2. Android中canvas.save()和canvas.restore()的使用

    自己定义控件时经常遇到重写View的Ondraw()方法,Ondraw()方法经常设计到save()和restore()这两个方法.这两个相互匹配出现的,作用是用来保存画布的状态和取出保存的状态的. ...

  3. POJ 3414 Pots 记录路径的广搜

    Description You are given two pots, having the volume of A and B liters respectively. The following ...

  4. OpenGL--第一个OpenGL程序

    环境:VS2012 + OpenGL所需文件(其他IDE也可以,不一定要VS2012,VS2010或其他也可以) 步骤: 1.下载Vs2012 2.下载OpenGL所需文件 3.解压缩OpenGL包并 ...

  5. uva 10003 Cutting Sticks(区间DP)

    题目连接:10003 - Cutting Sticks 题目大意:给出一个长l的木棍, 再给出n个要求切割的点,每次切割的代价是当前木棍的长度, 现在要求输出最小代价. 解题思路:区间DP, 每次查找 ...

  6. POJ1182 食物链 【并查集变种】

    挺简单的 N个元素扩展为 3*N个 i-A i-B i-C A吃B吃C吃A 挑战程序设计的89面 #include <cstdio> #include <cstdlib> #i ...

  7. hdu3485(递推)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3485 分析: a[i]表示长度为i,第i位为0的,符合情况的个数. b[i]表示长度为i,第i位为1的 ...

  8. tera term 残ALT债券

    Setup -> Keyboard对话框 Meta key变: left 版权声明:本文博客原创文章,博客,未经同意,不得转载.

  9. .Net 文本框实现内容提示(仿Google、Baidu)

    原文:.Net 文本框实现内容提示(仿Google.Baidu) 1.Demo下载: 文本框实现内容提示(仿Google.Baidu).rar 2.创建数据库.表(我用的sqlserver2008数据 ...

  10. Hibernate 配置详解(11)

    hibernate.session_factory_name_is_jndi 配置hibernate.cfg.xml中SessionFactory的name属性是否作为JNDI名称绑定.默认是true ...