zoukankan      html  css  js  c++  java
  • 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}	",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}	",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}	",evenNumber);
        }
        Console.WriteLine();
    }

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

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

    class Program
    {
       static void main(string[] args)
       {
         Console.Write("####More Fun With Lambdas####
    ");
         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####
    ");
         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####
    ");
         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();
    }

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

  • 相关阅读:
    Ajax
    模型层补充
    Django models.py 模型层(单表多表查询)
    Django 模板层
    Django views.py 视图层
    Django urls.py 路由层
    Browser Security-同源策略、伪URL的域
    Browser Security-css、javascript
    Browser Security-基本概念
    exp2:// 一次存储型XSS从易到难的挖掘过程
  • 原文地址:https://www.cnblogs.com/longProgrammer/p/3199586.html
Copyright © 2011-2022 走看看