zoukankan      html  css  js  c++  java
  • (C#)中断程序流程,处理事件(委托,事件,Lambda表达式)3/3

    C#匿名方法和Lambda表达式

    当一个调用者想监听传来的事件的时候,它必须定义一个唯一的与相关委托签名匹配的方法。

    在事件注册时直接将一个委托与一段代码相关联,这种代码叫做匿名方法。

    namespace ConsoleApplication1
    {
        class Program
        {
            public class Car
            {
                // 属性
                public string CarName { get; set; }
                public int CurrentSpeed { get; set; }
                public int MaxSpeed { get; set; }
    
                // 成员
                private bool carIsBroken;
    
                // 构造函数
                public Car() { MaxSpeed = 180; }
                public Car(string name, int maxSpd, int curSpd)
                {
                    CarName = name;
                    CurrentSpeed = curSpd;
                    MaxSpeed = maxSpd;
                   //carIsBroken = false; 
                }
    
                // 创建一个委托用于对Car事件的响应处理。
                //public delegate void CarEngineHandler(string msg);
                public delegate void CarEngineHandler(object sender, CarEventArgs e); 
    
                // Car类可以发送的事件
                public event CarEngineHandler eCarIsBroken;
                public event CarEngineHandler eOverSpeedAlarm;
    
                public void Accelerate(int delta)
                {
                    // 如果汽车已坏,触发eCarIsBroken事件
                    if (carIsBroken)
                    {
                        if (eCarIsBroken != null)    // 触发事件!
                        {
                            //eCarIsBroken("Car is broken,can't drive now!");
                            eCarIsBroken(this,new CarEventArgs("Car is broken,can't drive now!"));
                        }
                    }
                    else
                    {
                        CurrentSpeed += delta;
                    }
    
                    // 超速提醒
                    if (20 == MaxSpeed - CurrentSpeed && eCarIsBroken != null)  // 触发事件!
                    {
                        //eOverSpeedAlarm("Alarm: Going too fast, drive slowly!");
                        eOverSpeedAlarm(this,new CarEventArgs("Alarm: Going too fast, drive slowly!"));
                    }
    
                    if (CurrentSpeed >= MaxSpeed)
                    {
                        carIsBroken = true;
                    }
                    else
                    {
                        Console.WriteLine("CurrentSpeed = {0}", CurrentSpeed);
                    }
                }
            }
    
            // 利用EventArgs的派生类,来传递数据。
            public class CarEventArgs : EventArgs
            {
                public readonly string msg;
                public CarEventArgs(string message)
                {
                    msg = message;
                }
            }
    
    
            public static void TheCarIsBroken(string msg)
            {
                Console.WriteLine(msg);
            }
           
      
            static void Main(string[] args)
            {
                Car myCar = new Car("Audio Q5", 200, 60); 
    
                // 采用匿名的方式注册事件处理程序, 匿名方法的最后需要有一个分号结束
                myCar.eOverSpeedAlarm += delegate(object sender, CarEventArgs e)
                {
                    Console.WriteLine("{0}:{1}", sender, e.msg);
                };
    
                myCar.eCarIsBroken += delegate(object sender, CarEventArgs e)
                {
                    Console.WriteLine("{0}:{1}", sender, e.msg);
                };
    
    
                for (int i = 0; i < 12; i++)
                {
                    myCar.Accelerate(20);
                }
    
                Console.ReadLine();
            }
        }
    }

    Lambda表达式是匿名方法的简单表达方式,从而彻底的简化了对委托的使用。

    Lambada表达式是这样编写的:

    首先定义一个参数列表,随后加上“=>"标记,然后加上处理这些参数的语句。

    Lambda表达式的参数可以使显示类型化,也可以使隐式类型化的。

    举例说明如下:利用泛型List<T>的FindAll()方法从一组数据中找出所有的偶数。

    方法一:使用传统的委托方法

    namespace ConsoleApplication1
    {
        class Program
        {
            static void TraditionalDelegate()
            {
                // 创建整数列表
                List<int> myList = new List<int> { };
                myList.AddRange(new int[]{ 1, 2, 3, 4, 5, 9, 10, 21, 30, 68 });
    
                // 使用传统泛型委托语法调用FindAll
                Predicate<int> callback = new Predicate<int>(IsEvenNumber);
                List<int> evenNumbers = myList.FindAll(callback);
    
                // 输出结果
                foreach( int evenNumber in evenNumbers)
                {
                    Console.WriteLine("{0},",evenNumber);
                }
            }
           
            // Predicate 委托的目标方法
            static bool IsEvenNumber(int number)
            {
                return (0 == number % 2 ? true : false); 
            }
    
      
            static void Main(string[] args)
            {
                TraditionalDelegate();
                Console.ReadLine();
            }
        }

    方法二:使用匿名方法:

    // 使用传匿名委托语法调用FindAll
                List<int> evenNumbers = myList.FindAll(
                    delegate(int i)
                    {
                        return 0 == i % 2; 
                    });

    方法三:采用Lambda表达式

                // 使用Lambda表达式
                List<int> evenNumbers = myList.FindAll(
              i => 0 == (i % 2) );

    至此,我们用Lambda表达式来更新之前写的Car 事件

     static void Main(string[] args)
            {
                Car myCar = new Car("Audio Q5", 200, 60);
    
                // 使用Lambda表达式来挂起事件
                myCar.eOverSpeedAlarm += (sender, e) =>
                    {
                        Console.WriteLine(e.msg);
                    };
                myCar.eCarIsBroken += (sender, e) =>
                    {
                         Console.WriteLine(e.msg);
                    };
    
                for (int i = 0; i < 12; i++)
                {
                    myCar.Accelerate(20);
                }
    
                Console.ReadLine();
            }

     总结如下:

    1. delegate 关键字间接的构造了一个派生自MuticastDelegate的类,委托对象保存一个方法列表。可以被同步调用(Invoke()),或异步调用(BeginInvoke()和EndInvoke())

    2. event 关键字简化了事件发送到调用者的处理过程。

    3. 匿名方法可以直接将一段代码与指定事件相关联。Lambda表达式是匿名方法的简化表达方式。

  • 相关阅读:
    Tornado web 框架
    mysql_orm模块操作数据库(17.6.29)
    mysql小结篇3 索引、分页、执行计划--(17.6.28)
    Oracle触发器Trigger2行级
    Oracle触发器Trigger基础1
    Oracle函数function
    Oracle异常的抛出处理
    Oracle利用过程procedure块实现银行转账
    Oracle存储过程procedure
    PL/SQL块loop..各种循环练习
  • 原文地址:https://www.cnblogs.com/fdyang/p/2909868.html
Copyright © 2011-2022 走看看