Delegate,Annonymous Method,Extension Methods,Lambda Expression

简介:本文简单介绍委托、匿名方法、扩展方法和 Lambda Expression。 仅供初次接触这些技术的同学参考学习。

 List<int> list = new List<int> { 2, 3, 76, 63, 4, 64, 23 };

 //当你第一次看到下面这条语句时,你可能很难马上理解它的含义

 list.Where( x => x >20 );

 下面我们来一步一步演示它的演化过程。

 1. delegate

   委托是一种类型,它相当于 C++ 中的函数指针,指向一个特定的函数。

   如:public delegate int MyDelegate(int i);

  它定义了一个返回值为 int 且含有一个 int 型参数的委托 MyDelegate,凡是符合这种形式的方法都可以赋给我们的委托。  

  下面我们定义一个方法:

  public static int Fun(int i)  {   return i * 5;  }    

  这个方法符合我们定义的委托的形式:返回值为 int ,一个 int 型参数。  所以可以用来实例化我们的委托。

  MyDelegate del = new MyDelegate(Fun);

   //or

  //MyDelegate del = Fun;

  现在就可以用委托来调用我们的方法了:

  del(6);    

  委托其实是一个类,所以只能在类的外部定义。  那我们为什么多此一举用委托来调用函数呢?

  主要是一个委托可以指向具相同形式的多个函数,这使得委托可以实现很多灵活的应用。

  如实现很多好的设计模式,像观察者模式等,  C# 中的 event 等都是基于委托实现的。 

2. Annonymous Method(匿名方法)

    匿名方法就是一个没有名字的方法,下面我们赋给我们的委托一个匿名的方法  

    MyDelegate del = delegate(int i)  {   return i * 6;  };  

3. Lambda Expression

   有了 Lambda Expression 我们就可以这样写了   

   MyDelegate del = i => i * 6;

   是不是更简单了 => 左边的 i 是参数,右边是函数体(返回 i*6)。

   当有多个参数或函数体有多条语句时就可以写成这样了

   MyDelegate del = (x, y) =>     {      x = 3;      y = 5;      return x + y;     };      

4. Extension Methods   

   扩展方法可以给一个不可变的类添加方法,扩展方法是一个静态方法,不过可以用类的实例进行调用,

  看起来和调用类中的普通方法没什么区别。      

  下面我们扩展 string 类,增加一个 ToInt32Extension 方法

  public static class ExtensionMethods  

  {

    public static int ToInt32Extension(this string s)    

    {    

      return Int32.Parse(s);    

    }  

 }  

  扩展方法必须放在一个静态非泛型的类中,否则编译会出错。

  this 是扩展方法的关键字,后面跟上你要扩展的类。

  当然扩展方法也可以带参数,如  

  public static class ExtensionMethods

  {    

  public static int ToInt32ExtensionAddInteger(this string s,int value)    

   {    

     return Int32.Parse(s) + value;    

   }  

  }  

 下面我们就可以用类的实例就行调用了  

 string str = "45";

 s.ToInt32Extension();  

 也可直接调用静态方法如:

 ToInt32Extension(s);  

 不过不会这样用,这就体现不出扩展的意思了,但运行时应该就是把我们实例的引用传到静态方法中。

 

 扩展方法在 LINQ 查询中用的最多,看我们扩展自己的 where 查询子句。  

public static IEnumerable<TSource> MyOwnWhere<TSource>(this IEnumerable<TSource> source,      Func<TSource, bool> predicate)

 {   

  foreach (var item in source)   

  {  

      if (predicate(item))     

      yield return item;  

   }   

 }  

 IEnumerable<TSource>是我们要扩展的类,它是一个泛型类。

 同样它返回一个 IEnumerable<TSource> 集合。

 Func<TSource, bool>是参数,Func是一个泛型委托,它的返回值是 bool 类型。

 yield 的意思是将所有满足条件的 item 构成一个集合返回。

 

 这样我们就可以把筛选的条件作为函数传进去,当然就可以传匿名方法和  Lambda Expression 了。    

 最后让我们测试一下

 List<int> list = new List<int> { 2, 3, 76, 63, 4, 64, 23 };    

 //我们可以传一个匿名的方法进去  

 //var list2 = list.MyOwnWhere(delegate(int x){return x > 20;});  

 这里你可能要问我们没有扩展 List<T> 类啊? 为什么 List 的实例也能访问到呢?

 这是由于我们已经扩展了 IEnumerable<T> 接口 ,当你扩展一个接口时,

 所有实现这个接口的类的实例也都能访问到扩展方法了。当然 List<T> 是集合类,它实现了 IEnumerable<T> 接口。

 

 但更一般的是传一个 Lambda Expressions 进去

 你在LINQ查询中经常看到  

 var list2 = list.MyOwnWhere( x => x > 20);    

 foreach (int x in list2)  

{  

  Console.WriteLine(x);  

}  

最后它将返回数组中大于 20 的数字。

其它的 LINQ 扩展查询方法如 Select、Single、order by 等都是这样实现的。

现在希望你再看到这种表达式时不要感觉陌生了。

 

 

 

 

 

转载于:https://www.cnblogs.com/lesliefang/archive/2012/03/31/2427821.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值