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

原文:匿名方法,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+1
delegate(int x){return x+1;}
//也可以多个输入参数,逗号分隔,别忘记小括号
(x,y) => x+y
delegate(int x,int y){return x+y;}
//无参的也行
() => 1
delegate(){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

时间: 2024-11-09 14:09:59

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

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

概念了解: 1.什么是匿名委托(匿名方法的简单介绍.为什么要用匿名方法) 2.匿名方法的[拉姆达表达式]方法定义 3.匿名方法的调用(匿名方法的参数传递.使用过程中需要注意什么) 什么是匿名方法? 匿名方法是C#2.0引入的一个新特性,它允许开发者声明自己的函数代码而无须使用委托函数. C#为委托提供一种机制,可以为委托定义匿名方法,匿名方法没有名称,编译器会定指定一个名称,匿名方法中不能使用跳转语句跳转到该匿名方法的外部,也不能跳转到该方法的内部.也不能在匿名方法外部使用的ref和out参数.

委托-异步调用-泛型委托-匿名方法-Lambda表达式-事件

1. 委托 From: http://www.cnblogs.com/daxnet/archive/2008/11/08/1687014.html 类是对象的抽象,而委托则可以看成是函数的抽象.一个委托代表了具有相同参数列表和返回值的所有函数. [csharp] view plaincopy class Program { delegate int CalculateDelegate(int a, int b); int add(int a, int b) { return a + b; } s

委托delegate 泛型委托action&lt;&gt; 返回值泛型委托Func&lt;&gt; 匿名方法 lambda表达式 的理解

1.使用简单委托 namespace 简单委托 { class Program { //委托方法签名 delegate void MyBookDel(int a); //定义委托 static MyBookDel myBookDel; //普通方法 public static void MathBook(int a) { Console.WriteLine("我是数学书" + a); } static void Main(string[] args) { myBookDel += Ma

Scala高阶函数

1.作为参数的函数 函数可以作为一个参数传入到一个方法当中去 def main(args: Array[String]): Unit = { val myFunc1 =(x:Int) =>{ x * x } val myArray = Array(1,3,5,7,9).map(myFunc1) println(myArray.mkString(",")) } 2.匿名函数 没有名字的函数即是匿名函数,我们可以通过函数表达式来设置匿名函数 def main(args: Array[

【Scala】高阶函数和柯里化

高阶函数 在数学和计算机科学中,高阶函数是至少满足下列一个条件的函数: - 接受一个或多个函数作为输入 - 输出一个函数 在数学中它们也叫做算子(运算符)或泛函.微积分中的导数就是常见的例子,因为它映射一个函数到另一个函数. 高阶函数的例子 假设有一个函数对给定两个数区间中的所有整数求和: def sumInts(a: Int, b: Int): Int = if(a > b) 0 else a + sumInts(a + 1, b) 如果现在要求连续整数的平方和: def square(x:

python--函数式编程 (高阶函数(map , reduce ,filter,sorted),匿名函数(lambda))

1.1函数式编程 面向过程编程:我们通过把大段代码拆成函数,通过一层一层的函数,可以把复杂的任务分解成简单的任务,这种一步一步的分解可以称之为面向过程的程序设计.函数就是面向过程的程序设计的基本单元. 函数式编程:是使用一系列函数去解决问题,函数式编程就是根据编程的范式来的出想要的结果,只要是输入时确定的,输出就是确定的. 1.2高阶函数 能把函数作为参数传入,这样的函数就称为高阶函数. 1.2.1函数即变量 以python的内置函数print()为列,调用该函数一下代码 >>> pri

python高阶函数,map,filter,reduce,ord,以及lambda表达式

为什么我突然扯出这么几个函数,是因为我今天在看流畅的python这本书的时候,里面有一部分内容看的有点懵逼. >>> symbols = '$¢£¥€¤' >>> beyond_ascii = [ord(s) for s in symbols if ord(s) > 127] >>> beyond_ascii [162, 163, 165, 8364, 164] >>> beyond_ascii = list(filter(la

Python: 高阶函数与lambda表达式

缘由: python语法简单一看就会,但用在实处,想因为少于实战,总感觉有些捉襟. 翻阅跟踪youtube_dl源码,看到filter()函数用法,及其中lambda表达式,感觉好有意思,就补下课,记录所思. 1. 高阶函数 所谓高阶函数,即是能接受函数做参数的函数.函数做参,与c#委托.c++函数指针.Delphi事件有类似之处 比如: def my_func(f, *args): f(args) def my_print(s): print ', '.join(s) my_func(my_p

Python进阶:函数式编程(高阶函数,map,reduce,filter,sorted,返回函数,匿名函数,偏函数)...啊啊啊

函数式编程 函数是Python内建支持的一种封装,我们通过把大段代码拆成函数,通过一层一层的函数调用,就可以把复杂任务分解成简单的任务,这种分解可以称之为面向过程的程序设计.函数就是面向过程的程序设计的基本单元. 而函数式编程(请注意多了一个"式"字)--Functional Programming,虽然也可以归结到面向过程的程序设计,但其思想更接近数学计算. 我们首先要搞明白计算机(Computer)和计算(Compute)的概念. 在计算机的层次上,CPU执行的是加减乘除的指令代码