【C#与.NET程序设计】(8)- C#事件、Lambda

来源:互联网 发布:捕鱼游戏算法 编辑:程序博客网 时间:2024/06/04 19:17

事件(Event)

  • 其实质就是具有特殊签名的委托,事件处理的就是委托链表的方法
  • 事件可以解决委托带来的“封装不完善”的问题:
    由于delegate的目的是为了将其暴露在类的客户端进行方法的注册,因此必须是 public 的
    但这样一来,在客户端就可以对其进行随意的函数绑定,严重破坏对象的封装性
  • 对于事件,无论内部的委托类型是 public 还是 protected,它总是 private的;在类的外部,注册“+=”和注销“-=”的访问限定符与委托类型限定符一致

事件的具体描述:

事件是类在发生其关注的事情时用来提供通知的一种方式

牵涉到2个角色:
1. 事件发布者:这个对象维护状态信息,当发生改变时便触发一个事件,并通知所有的事件订阅者
2. 事件订阅者:可以注册感兴趣的事件,在发布者触发一个事件后自动执行这段代码

// 代码来自:http://www.cnblogs.com/wudiwushen/archive/2010/04/20/1703763.html//发布者(Publiser)public class Publisher{    //声明一个出版的委托    public delegate void PublishEventHander();    //在委托的机制下我们建立一个出版事件    public event PublishEventHander OnPublish;    //事件必须要在方法里去触发,出版社发布新书方法    public void issue()    {        //如果有人注册了这个事件,也就是这个事件不是空        if (OnPublish != null)        {            Console.WriteLine("最新一期的《火影忍者》今天出版哦!");            OnPublish();        }    }}//Subscriber 订阅者,无赖小明public class MrMing{    //对事件感兴趣的事情,这里指对出版社的书感兴趣    public static void Receive()    {        Console.WriteLine("嘎嘎,我已经收到最新一期的《火影忍者》啦!!");           }}//Subscriber 订阅者,悲情人物小张public class MrZhang{    //对事件感兴趣的事情    public static void Receive()    {        Console.WriteLine("幼稚,这么大了,还看《火影忍者》,SB小明!");    }}class Story{    public static void Main(string[] args)    {        //实例化一个出版社        Publisher publisher = new Publisher();         //给这个出火影忍者的事件注册感兴趣的订阅者,此例中是小明        publisher.OnPublish += new Publisher.PublishEventHander(MrMing.Receive);        //另一种事件注册方式        //publisher.OnPublish += MrMing.Receive;        //发布者在这里触发出版火影忍者的事件        publisher.issue();        Console.ReadKey();    }}

事件的匿名

一般来说上面的 Receive 函数只是为了响应事件的调用,为了更简洁(不用去想方法名字),可以使用匿名的方式

class Story{    public static void Main(string[] args)    {        Publisher publisher = new Publisher();         publisher.OnPublish += delegate{            // 实现 Receive 的逻辑         };  // 注意有个分号        publisher.issue();        Console.ReadKey();    }}

Lambda

微软对C#的路线是: 委托 -> 匿名表达式 -> Lambda表达式
搬自文章《C# Lambda表达式》,对照下一个加法在三种方式下的实现

delegate int calculator(int x, int y); //委托类型// 委托public static int Adding(int x, int y){    return x + y;}static void Main(){    calculator cal = new calculator(Adding);    int He = cal(1, 1);    Console.Write(He);}// 对委托类型的简化// Action<T>static void Main(){    Action<int, int> cal = new Action<int, int>(Adding);    int he = cal(1, 1);    Console.Write(he);}// Func<T>// 相较 Action,最后一个参数为输出参数static void Main(){    Func<int, int, void> cal = new Func<int, int>(Adding);    int he = cal(1, 1);    Console.Write(he);}// 对委托函数的简化// 匿名static void Main(){    calculator cal = delegate(int num1,int num2)    {        return num1 + num2;    };    int he = cal(1, 1);    Console.Write(he);}// Lambdastatic void Main(){    calculator cal = (x, y) => x + y;    int he = cal(1, 1);    Console.Write(he);}

可以看到Lambda的基本形式:(输入参数)=>表达式

  • 只有1个参数时,可以省略括号:()=>、(x)=>、x=>、(x,y)=>
  • 包含多个表达式时,使用“{}+;”:(x)=>{语句1;语句2;};

一般结合 Func 达到委托类型和委托函数的简化

static void Main(string[] args){    Func<int, int, bool> gwl = (p, j) =>    {        if (p + j == 10)        {            return true;        }        return false;    };    Console.WriteLine(gwl(5,5) + "");    Console.ReadKey();}

阅读全文
0 0
原创粉丝点击