匿名方法,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表达式,高阶函数的更多相关文章
- C# delegate event func action 匿名方法 lambda表达式
delegate event action func 匿名方法 lambda表达式 delegate类似c++的函数指针,但是是类型安全的,可以指向多个函数, public delegate void ...
- 18、(番外)匿名方法+lambda表达式
概念了解: 1.什么是匿名委托(匿名方法的简单介绍.为什么要用匿名方法) 2.匿名方法的[拉姆达表达式]方法定义 3.匿名方法的调用(匿名方法的参数传递.使用过程中需要注意什么) 什么是匿名方法? 匿 ...
- 匿名函数 =匿名方法+ lambda 表达式
匿名函数的定义和用途 匿名函数是一个"内联"语句或表达式,可在需要委托类型的任何地方使用. 可以使用匿名函数来初始化命名委托[无需取名字的委托],或传递命名委托(而不是命名委托类型 ...
- 委托-异步调用-泛型委托-匿名方法-Lambda表达式-事件【转】
1. 委托 From: http://www.cnblogs.com/daxnet/archive/2008/11/08/1687014.html 类是对象的抽象,而委托则可以看成是函数的抽象.一个委 ...
- C#多线程+委托+匿名方法+Lambda表达式
线程 下面是百度写的: 定义英文:Thread每个正在系统上运行的程序都是一个进程.每个进程包含一到多个线程.进程也可能是整个程序或者是部分程序的动态执行.线程是一组指令的集合,或者是程序的特殊段,它 ...
- C#委托总结-匿名方法&Lambda表达式
1,匿名方法 匿名方法可以在声明委托变量时初始化表达式,语法如下 之前写过这么一段代码: delegate void MyDel(string value); class Program { void ...
- 委托delegate 泛型委托action<> 返回值泛型委托Func<> 匿名方法 lambda表达式 的理解
1.使用简单委托 namespace 简单委托 { class Program { //委托方法签名 delegate void MyBookDel(int a); //定义委托 static MyB ...
- Scala高阶函数
1.作为参数的函数 函数可以作为一个参数传入到一个方法当中去 def main(args: Array[String]): Unit = { val myFunc1 =(x:Int) =>{ x ...
- Kotlin高阶函数实战
前言 1. 高阶函数有多重要? 高阶函数,在 Kotlin 里有着举足轻重的地位.它是 Kotlin 函数式编程的基石,它是各种框架的关键元素,比如:协程,Jetpack Compose,Gradle ...
随机推荐
- haproxy 中的http请求和https请求
use Mojolicious::Lite; use JSON qw/encode_json decode_json/; use Encode; no strict; use JSON; # /foo ...
- C++环形矩阵填充实现
#include<iostream> #include<iomanip> #include<cstdlib> #include<ctime> #incl ...
- 关于JVM的ClassLoader(转)
众所周知,java是编译型的语言,写的是java文件,最后运行的是class文件,class文件是运行在JVM之中的,这时候就有一个问题,JVM如何装载class文件的?是通过ClassLoader来 ...
- js使用栈来实现10进制转8进制 js取除数 余数
function ten2eight(x){ var s=[]; var r=''; while(x>0){ s.push(x%8); x=parseInt(x/8); } while(s.le ...
- Linux IO 调度器
Linux IO Scheduler(Linux IO 调度器) 每个块设备或者块设备的分区,都对应有自身的请求队列(request_queue),而每个请求队列都可以选择一个I/O调度器来协调所递交 ...
- ubuntu Linux 安装和首次使用
1.ubuntu Linux 安装后切换到root账户,在默认情况下,系统安装过程中需要创建一个用户,切换到root账号命令如下:$ sudo -s -H输入 当前账户密码就可以切换到root.2.u ...
- 从零開始学android<SeekBar滑动组件.二十二.>
拖动条能够由用户自己进行手工的调节,比如:当用户须要调整播放器音量或者是电影的播放进度时都会使用到拖动条,SeekBar类的定义结构例如以下所看到的: java.lang.Object ↳ an ...
- 【Java】运用JDBC实现一个注册、登录系统的编写
数据库的建立 首先,建立一个数据库,存储注册成功的账户信息. 其SQL的DDL语句如下: CREATE TABLE `jdbctest` ( `id` int(10) NOT NULL auto_in ...
- Scala的XML操作
8. XML 8.1. 生成 Scala原生支持xml,就如同Java支持String一样,这就让生成xml和xhtml非常easy优雅: val name = "james ...
- FAAC1.28 在海思HI3520D/HI3515A平台linux中的编译 优化
FAAC1.28的下载地址:http://www.audiocoding.com/downloads.html 怎样编译: 1../configure --host=arm-hisiv100nptl- ...