C#委托与Lambda表达式

转自:http://www.cnblogs.com/nokiaguy/archive/2008/06/09/1216166.html

本文介绍了.net 3.5 framework中的Lambda表达式。这种表达式可以取代delegate,作为方法指针来使用。

    在C#2.0及C#1.x中,需要使用delegate来定义方法指针。如下面的代码如示:

public delegate bool Filter(int num);  //
delegate类型

public int[] searchArray(int[] values, Filter filter)
{
    List<int> result = new List<int>();
   
foreach (int i in values)
   
{
         if (filter(i))
             result.Add(i);
   
}           
    return result.ToArray();
}

    从上面的代码可以看出,定义了一个叫Filter的delegate类型。然后searchArray方法的第二个参数通过Filter类型将方法指针传到该方法中。 实际上,从IL可以看出,Filter被编译成了一个类,而且这个类是System.MulticastDelegate的子类。但和普通类不同的是,System.MulticastDelegate及其子类只能由编译器使用,不能直接写在源程序中。也就是说,只能在IL中使用。

    如果要调用searchArray方法,需要先定义一个和Filter拥有同样参数和返回值的方法,代码如下:

public bool MyFilter(int num)
{
    return ((num & 1) == 0);
}

    下面的代码调用了searchArray方法:

int[] intArray = new int[] { 1, 2, 3, 4, 5, 6, 7, 8 };
int[] evenArray = searchArray(intArray, MyFilter);
foreach (int i in evenArray)
   
textBox1.AppendText(i.ToString());

    从C#2.0开始支持匿名方法,开发人员可以通过匿名方法用内联代码形式取代delegate,如上面的调用代码可以修改为下面的形式:

int[] intArray = new int[] { 1, 2, 3, 4, 5, 6, 7, 8 };
int[] evenArray = searchArray(intArray, delegate(int i) { return ((i & 1) == 0); });
foreach (int i in evenArray)
   
textBox1.AppendText(i.ToString());

    上面的代码将匿名方法转换成了delegate。

    然而,从C#3.0(.net
framework3.5)开始,支持了Lambda表达式。所谓Lambda表达式就是delegate和匿名方法的简写形式,Lambda表达式的语法如下:

(param1, param2 ...,paramN) =>

{

    表达式1;

    表达式2;

    return 返回值;

}

    上面语法中的param1...paramN就表示方法的参数(不用确定类型,C#编译器会为我们做这个工作),而{...}里面的内容就和方法体中的内容完全一样。

    如果delegate没有参数,可以只写(),如下面的方法所示:

public delegate void Method1();

public void test()
{
    Method1 method1 = () => { int i = 4; i += 6; };
}

    如果delegate只有一个参数,参数两边的括号可以不写,代码如下:

public delegate void Method2(int i);

public void test()
{
    Method2 method2 = i => { i++; i += 6; };
}

 

    如果delegate有返回值,{...}中的最后一条语句需要使用return来返回相应的值,代码如下:

public delegate int Method3(int x, int y);

public void test()
{
    Method3 method3 = (x, y) => { x++; y++; return x + y; };
}

   
如果使用Lambda表达式改写本文开头的例子,就会变得非常简单,代码如下:

int[] intArray = new int[] { 1, 2, 3, 4, 5, 6, 7, 8 };
int[] evenArray = searchArray(intArray, i => { return (i & 1) == 0; });
foreach (int i in evenArray)
   
textBox1.AppendText(i.ToString());

   
当然,我们也可以将Lamdba表达式赋给一个delegate,再进行传值,代码如下;

Filter filter = i => { return (i & 1) == 0; };     
int[] intArray = new int[] { 1, 2, 3, 4, 5, 6, 7, 8 };
int[] evenArray = searchArray(intArray, filter);
foreach (int i in evenArray)
    textBox1.AppendText(i.ToString());

   
从本质上讲,Lamdba表达式经过C#编译器编译后,仍然会变成delegate的形式,也就是说Lamdba表达式只是在语法层次上的改进,并不是IL提供的新的指令。如下面的两行代码是等价的:

Filter filter = i => { return (i & 1) == 0; };       
Filter filter = delegate(int i) { return ((i & 1) == 0); };

 

时间: 2024-09-22 23:10:30

C#委托与Lambda表达式的相关文章

为LINQ服务的C#新特性总结篇---扩展方法,匿名委托,lambda表达式,Action委托,Func委托,Linq中的order by,top和sum函数

Codeusing System;using System.Collections.Generic;using System.Linq;using System.Text; using System.Diagnostics; namespace ConsoleApplication1{    static class Program    {        static void Main(string[] args)        {            //Predicate       

使用Action、Func,EventHandler,params关键字修饰的参数的匿名委托和Lambda表

使用Action.Func,EventHandler,params关键字修饰的参数的匿名委托和Lambda表达式 在.NET在,我们经常使用委托,委托的作用不必多说,在.NET 2.0之前,我们在使用委托之前,得自定义一个委托类型,再使用这个自定义的委托类型定义一个委托字段或变量..NET 2.0给我们带来了Action.Func两个泛型委托,.NET3.0给我们带来了Lambda,这一切使得委托的定义和使用变得简单起来.下面的例子中的委托都使用了Lambda表达式. 一.Action系列的泛型

C# 委托,事件和Lambda表达式

关于这个论题,Delegates, Events, and Lambda Expressions 对此有比较深入的分析,可以参考.C# vs C++之一:委托 vs 函数指针 比较了委托和C++指针的区别. .NET 中的委托确实和C/C++的函数指针非常相似.它是一个值类型,它包装了一个指向方法的引用.它的作用也是为了能够将方法和变量一样作为参数传递.委托的典型应用是控件的事件处理方法.很显然,一个控件在设计的时候没有办法知道当特定事件发生的时候,需要什么方法来处理,这就需要将方法作为参数传递

从.NET中委托写法的演变谈开去(中):Lambda表达式及其优势

在上一篇文章中我们简单探讨了.NET 1.x和.NET 2.0中委托表现形式的变化,以及.NET 2.0中匿名方法的优势.目的及注意事项.那么现在我们来谈一下.NET 3.5(C# 3.0)中,委托的表现形式又演变成了什么样子,还有什么特点和作用. .NET 3.5中委托的写法(Lambda表达式) Lambda表达式在C#中的写法是"arg-list => expr-body","=>"符号左边为表达式的参数列表,右边则是表达式体(body).参数列表

C#委托基础8——lambda表达式

  C#委托基础系列原于2011年2月份发表在我的新浪博客中,现在将其般至本博客. class Program { double AddInt(int x, int y) { return x + y; } string AddString(string s1, string s2) { return s1 + s2; } static void Main(string[] args) { Program p = new Program(); // 以为前两个参数为int,他们运行的结果为dou

一起谈.NET技术,C# 委托,事件和Lambda表达式

关于这个论题,Delegates, Events, and Lambda Expressions 对此有比较深入的分析,可以参考.C# vs C++之一:委托 vs 函数指针 比较了委托和C++指针的区别. .NET 中的委托确实和C/C++的函数指针非常相似.它是一个值类型,它包装了一个指向方法的引用.它的作用也是为了能够将方法和变量一样作为参数传递.委托的典型应用是控件的事件处理方法.很显然,一个控件在设计的时候没有办法知道当特定事件发生的时候,需要什么方法来处理,这就需要将方法作为参数传递

一起谈.NET技术,从.NET中委托写法的演变谈开去(中):Lambda表达式及其优势

在上一篇文章中我们简单探讨了.NET 1.x和.NET 2.0中委托表现形式的变化,以及.NET 2.0中匿名方法的优势.目的及注意事项.那么现在我们来谈一下.NET 3.5(C# 3.0)中,委托的表现形式又演变成了什么样子,还有什么特点和作用. .NET 3.5中委托的写法(Lambda表达式) Lambda表达式在C#中的写法是"arg-list => expr-body","=>"符号左边为表达式的参数列表,右边则是表达式体(body).参数列表

C# 3.0新特性体验之Lambda表达式

C#2.0介绍了一个新特性--匿名方法,允许开发者在线(inline)声明自己的函数代码而无须使用委托函数(delegate function).C#3.0中提供了一个新特性--Lambda表达式,它提供了完成相同目标的更加简洁的格式.让我们在讨论Lambda表达式以前仔细研究一下匿名方法. 匿名方法 假设你需要创建一个按钮,当点击它的时候更新ListBox里的内容.在C#1.0和1.1里,你要这样做: public MyForm(){ listBox = new ListBox(...); t

关于Lambda表达式

Lambda表达式是C#3.0的一种新语法,语法简洁 为编写匿名方法提供了更简明的函数式的句法. 我通过一个示例来说明Lambda表达式的原理: Lambda表达式和匿名方法都来源于委托 我们来看看委托的使用 在C#1.0时: 1using System; 2using System.Collections.Generic; 3using System.Linq; 4using System.Text; 5 6namespace ConsoleApplication3 7{ 8 public d