原文:匿名方法,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. 数据挖掘 决策树算法 ID3 通俗演绎

    决策树是对数据进行分类,以此达到预測的目的.该决策树方法先依据训练集数据形成决策树,假设该树不能对全部对象给出正确的分类,那么选择一些例外添�到训练集数据中,反复该过程一直到形成正确的决策集.决策树代 ...

  2. div仿checkbox表单样式美化及功能

    div仿checkbox表单样式美化及功能(checkbox的样式不好看)素材在底部: 效果图: window.css .bj { position: absolute; top: 0; left: ...

  3. OCA读书笔记(16) - 执行数据库恢复

    16. Performing Database Recovery 确定执行恢复的必要性访问不同接口(EM以及命令行)描述和使用可用选项,如RMAN和Data Recovery Advisor执行恢复- ...

  4. Enable OWIN Cross-origin Request

    微软出了一套解决方式能够解决 "同意WebAPI的 CORS 请求" http://www.asp.net/web-api/overview/security/enabling-c ...

  5. nginx fastcgi 自定义错误页面

    http{ fastcgi_intercept_errors on; error_page 404 /404.html; } fastcgi_intercept_errors on;必须设置 之后通过 ...

  6. oschina 手机/移动开发

    手机/移动开发 Android UI 组件(167) React Native 相关(8) 网站客户端(16) NativeScript 插件(18) iPhone/iPad开发工具(16) WP7开 ...

  7. hdu1243(最长公共子序列变形)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1243 分析:dp[i][j]表示前i个子弹去炸前j个恐怖分子得到的最大分.其实就是最长公共子序列加每个 ...

  8. HDU 4869 Turn the pokers(推理)

    HDU 4869 Turn the pokers 题目链接 题意:给定n个翻转扑克方式,每次方式相应能够选择当中xi张进行翻转.一共同拥有m张牌.问最后翻转之后的情况数 思路:对于每一些翻转,假设能确 ...

  9. SE 2014年5月25日

    如图配置 两实验 R1模拟总部,R2 与R3模拟分部 实验一  要求使用 IPSec VPN 主模式,使得总部与两分部内网可相互通讯 步骤: 1.  配置默认路由 [RT1]ip route-stat ...

  10. MYSQL中的字符串连接符

    update `table` set nsdf = concat('a','b') where id=137