C#委托与Lambda表达式

简介: 转自:http://www.cnblogs.com/nokiaguy/archive/2008/06/09/1216166.html本文介绍了.net 3.5 framework中的Lambda表达式。

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

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

    C#2.0C#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); };

 

目录
相关文章
|
3月前
|
开发框架 自然语言处理 .NET
C#一分钟浅谈:LINQ 查询表达式的使用技巧
【9月更文挑战第6天】LINQ(Language Integrated Query)是C#开发中的强大工具,使查询数据集合变得简单且接近自然语言。本文从基础入手,通过具体示例讲解LINQ查询表达式的使用技巧,包括过滤、排序和分组等操作。同时,文章还探讨了常见问题及解决方法,如性能优化、过早枚举和类型转换等,帮助开发者写出更高效、易维护的代码。
103 15
|
3月前
|
C#
C#一分钟浅谈:委托与事件的实现方式
本文详细介绍了C#编程中委托与事件的基础知识及应用场景。首先解释了委托的概念,包括定义与使用方法;接着介绍了事件这一基于委托的特殊类型,展示了如何在类中定义事件及跨类订阅与处理事件;最后讨论了常见问题如事件未处理异常、重复订阅及内存泄漏等,并提出了相应的解决方案。通过本文,读者将全面掌握委托与事件的使用技巧,提升应用程序的设计与开发水平。
141 7
|
3月前
|
C#
C#一分钟浅谈:Lambda 表达式和匿名方法
本文详细介绍了C#编程中的Lambda表达式与匿名方法,两者均可用于定义无名函数,使代码更简洁易维护。文章通过基础概念讲解和示例对比,展示了各自语法特点,如Lambda表达式的`(parameters) =&gt; expression`形式及匿名方法的`delegate(parameters)`结构。并通过实例演示了两者的应用差异,强调了在使用Lambda时应注意闭包问题及其解决策略,推荐优先使用Lambda表达式以增强代码可读性。
48 8
|
4月前
|
编译器 C#
C#中内置的泛型委托Func与Action
C#中内置的泛型委托Func与Action
68 4
|
4月前
|
C#
C#中的委托(一)
C#中的委托(一)
41 1
|
5月前
|
SQL 开发框架 前端开发
在C#开发中使用第三方组件LambdaParser、DynamicExpresso、Z.Expressions,实现动态解析/求值字符串表达式
在C#开发中使用第三方组件LambdaParser、DynamicExpresso、Z.Expressions,实现动态解析/求值字符串表达式
|
4月前
|
C# C++
C#语言进阶(一)—委托
C#语言进阶(一)—委托
52 0
|
7月前
|
存储 安全 C#
C# - 委托与事件
这篇文档介绍了C#中的委托和事件。委托是存储方法引用的类型,支持回调、事件处理,具有引用方法、类型安全、多播性等特性,并在异步编程中发挥作用。事件是委托的封装,提供保护和订阅机制,防止外部直接访问。当需要在类内部控制方法调用,防止外部误触发时,可使用事件。
|
6月前
|
C#
C#||委托和事件的实例
C#||委托和事件的实例
|
1月前
|
C# 开发者
C# 一分钟浅谈:Code Contracts 与契约编程
【10月更文挑战第26天】本文介绍了 C# 中的 Code Contracts,这是一个强大的工具,用于通过契约编程增强代码的健壮性和可维护性。文章从基本概念入手,详细讲解了前置条件、后置条件和对象不变量的使用方法,并通过具体代码示例进行了说明。同时,文章还探讨了常见的问题和易错点,如忘记启用静态检查、过度依赖契约和性能影响,并提供了相应的解决建议。希望读者能通过本文更好地理解和应用 Code Contracts。
34 3
AI助理

阿里云 AI 助理已上线!

快来体验一下吧。