Lambda表达式(第六章)

  C#支持内联处理事件,通过直接把一段代码语句赋值给事件(使用匿名方法),而不是构建被底层委托调用的独立方法。Lambda表达式只是用更简单的方式来写匿名方法,彻底简化了对.net委托类型的使用。

  为了对Lambda表达式的研究做准备,先看如下program类型的新方法:

static void AnonymousMethodSyntax()
{
    //建立整数列表
   List<int> list=new List();
    list.AddRange(new int[]{20,1,4,8,9,44});
    //现在使用匿名方法
   List<int> evenNumbers=list.FindAll(delegate(int i)
    {
        return (i%2)==0;
    });
    ConsoleWriteLine("Here are your even numbers:");      
    foreach(int evenNumber in evenNumbers)
    {
       Console.Write("{0}\t",evenNumber);
    }
    Console.WriteLine();
}

  以上代码我们并不是首先创建一个Predicate<T>委托类型,然后编写一个独立方法,而是使用了一个匿名方法。虽然这是正确方向,但是仍然需要使用关键字delegate(或者一个强类型化的Predicate<T>,而且还需要保证输入参数百分之百匹配。我们认为,定义匿名方法的语法还是有点冗长。下面代码可以说明这个问题:

List<int> evenNumbers =list.FindAll(
   delegate(int i)
   {
       return (i%2)==0;
    }
);

  我们可以用Lambda表达式进一步简化方法FindAll()的调用。使用新方法时,底层委托语法将会消失得无影无踪:

static void LambdaExpressionSyntax()
{
    //建立整数列表
   List<int> list=new List();
    list.AddRange(new int[]{20,1,4,8,9,44});
    //现在使用拉姆达表达式
   List<int> evenNumbers=list.FindAll(i=>(i%2)==0);
    ConsoleWriteLine("Here are your even numbers:");      
    foreach(int evenNumber in evenNumbers)
    {
       Console.Write("{0}\t",evenNumber);
    }
    Console.WriteLine();
}

  在深入了解表达式的语法前,我们需要知道Lambda表达式可以应用于任何匿名方法可以应用的场合,而且比匿名方法更节省编码时间。其实C#编译器只是把表达式翻译为使用委托Predicate<T>的普通匿名方法而已。

  使用多个语句处理参数

  当表达式必须使用多行代码处理参数时,你可以使用一对花括号确定这些语句的范围:

static void LambdaExpressionSyntax()
{
    //建立整数列表
   List<int> list=new List();
    list.AddRange(new int[]{20,1,4,8,9,44});
    //现在使用语句块编写拉姆达表达式
   List<int> evenNumbers=list.FindAll(
     {
       Console.WriteLine("value of i is currently:{0}",i);
       bool isEven=((i%2)==0);
       return isEven;
     });
    ConsoleWriteLine("Here are your even numbers:");      
    foreach(int evenNumber in evenNumbers)
    {
       Console.Write("{0}\t",evenNumber);
    }
    Console.WriteLine();
}

  使用Lambda表达式重新编写CarDelegate示例

  先看CarDelegate的简化版本,它使用传统的委托语法响应每个回调:

class Program
{
   static void main(string[] args)
   {
     Console.Write("####More Fun With Lambdas####\n");
     Car cl=new Car("SlugBug",100,10);
     cl.OnAboutToBlow(new Car.AboutToBlow(CarAboutToBlow));
     cl.OnExploded(new Car.Exploded(CarExploded));
     Console.WriteLine("Speed up");
     for(int i=0;i<7;i++)
      cl.Accelerate(20);
     Console.ReadLine();
   }
   //委托目标
   public static void CarAboutToBlow(string msg)
   { Console.WriteLine(msg);
   }
   public static void CarExploded(stirng msg)
   { Console.WriteLine(msg);}
}

  下面是使用匿名方法的语法重写的Main

class Program
{
   static void main(string[] args)
   {
     Console.Write("####More Fun With Lambdas####\n");
     Car cl=new Car("SlugBug",100,10);
     cl.OnAboutToBlow(delegate(string msg){Console.WriteLine(msg);});
     cl.OnExploded(delegate(string msg){Console.WriteLine(msg);});

     Console.WriteLine("Speed up");
     for(int i=0;i<7;i++)
      cl.Accelerate(20);
     Console.ReadLine();
   }
}

  下面是使用Lambda表达式重新编写的Main():

class Program
{
   static void main(string[] args)
   {
     Console.Write("####More Fun With Lambdas####\n");
     Car cl=new Car("SlugBug",100,10);
     cl.OnAboutToBlow(msg=>{Console.WriteLine(msg);});
     cl.OnExploded(msg=>{Console.WriteLine(msg);});
     Console.WriteLine("Speed up");
     for(int i=0;i<7;i++)
      cl.SpeedUp(20);
     Console.ReadLine();
   }
}

   含有多个(或零个)参数的Lambda表达式

  假设SimpleMath有如下更新

public class SimpleMath
{
    public delegate void MathMessage(string msg,int result);
    private MathMessage mmDelegate;
    public void SetMathHandler(MathMessage target)
    {
       mmDelegate=target;
    }
    public int Add(int x,int y)
    {
       if(mmDelegate!=null)
         mmDelegate.Invoke("Adding has completed!",x+y);
    }
}
//我们看到,委托MathMessage需要两个参数。使用Lambda表达式的Main()如下:
static void Main(string[] args)
{
   //使用Lambda表达式注册委托
   SimpleMath m=new SimpleMath();
    m.SetMathHandler(msg,result)=>
    {Console.WriteLine("Message:{0},Result:{1},msg,result);});
   //执行Lambda表达式
   m.Add(10,10);
    Console.ReadLine();
}

  以上只是学习的皮毛,有不当之处望各位博友指正。

posted @ 2013-07-18 23:22  DBNull  阅读(363)  评论(0编辑  收藏  举报