zoukankan      html  css  js  c++  java
  • C#高级编程 (第六版) 学习 第七章:委托和事件

    第七章 委托和事件

    回调(callback)函数是Windows编程的一个重要方面,实际上是方法调用的指针,也称为函数指针。

    .Net以委托的形式实现了函数指针的概念,.Net的委托是类型安全的。

    1. 委托

    使用委托的时候,需要先声明,后实例化。

    声明委托

    delegate void MethodInvoker();

    可以在委托前加public,private,protected。

     

    实际上,定义委托是指定义一个新类,委托实现为派生自基类System.MulticastDelegate。

     

    使用委托

    private delegate string GetAString();

     

    static void Main()

    {

        int x = 10;

        GetAString firstMethod = new GetAString(x.ToString);

        Console.WriteLine("String is {0}", firstMethod());

        // Console.WriteLine("String is {0}", firstMethod.Invoke());

     

     

    }

    委托在语法上总是带有一个参数的构造函数,这个参数就是委托引用的方法

    C#引入和委托推断:

    GetAString firstMethod = x.ToString;

     

    多播委托

    包含多个方法调用的委托。调用委托的个数也与方法相同

    delegate void DoubleOp(double value);

     

    DoubleOp operations = MathOperations.MultiplyByTwo;

    operations += MathOperations.Square;

    operations(2.0);

    会执行两个函数

    也可使用-=

    多播委托包含一个逐个调用的委托集合。如果通过委托调用的一个方法抛出了异常,整个迭代就会停止。解决方法:

    DemoDelegate d1 = One;

    d1 += Two;

     

    Delegate[] delegates = d1.GetInvocationList();

    foreach(DemoDelegate d in delegates)

    {

        try

        {

        }

        catch(Exception)

        {

        }

    }

     

    匿名方法

    delegate string DelegateTest(string val);

    DelegateTest an1 = delegate(string param)

    {

        statements;

    };

     

    lambada表达式

    C#3.0引入,创建匿名函数

    DelegateTest an1 = param =>

    {

        statements;

        return "some string";

    };

    lambada表达式中,运算符=>左边列出了参数类型和个数

    可以忽略类型,只写标识符,用括号括住,当标识符只有一个时,可以省略括号。

     

    1. 事件

    例子

    using System;

    using System.Collections.Generic;

    using System.Linq;

    using System.Text;

    using System.Timers;

     

    namespace Chapter_7

    {

    public delegate void MessageHandler(string messageText);

     

    public class Connection

    {

    public event MessageHandler MessageArrived;

    private Timer pollTimer;

    private static Random random = new Random();

    private uint count = 0;

     

    public Connection()

    {

    pollTimer = new Timer(100);

    pollTimer.Elapsed += new ElapsedEventHandler(CheckForMessage);

    }

     

    public void Connect()

    {

    pollTimer.Start();

    }

     

    public void Disconnect()

    {

    pollTimer.Stop();

    }

     

    private void CheckForMessage(object source, ElapsedEventArgs e)

    {

    Console.WriteLine("Checking for new message.");

    if ((random.Next(9) == 0) && (MessageArrived != null))

    {

    count++;

    MessageArrived("Hello Mum!");

    }

    }

    }

    }

    using System;

    using System.Collections.Generic;

    using System.Linq;

    using System.Text;

     

    namespace Chapter_7

    {

    public class Display

    {

    public void DisplayMessage(string message)

    {

    Console.WriteLine("message arrived:{0}", message);

    }

    }

    }

    using System;

    using System.Collections.Generic;

    using System.Linq;

    using System.Text;

     

    namespace Chapter_7

    {

    public delegate void DoubleOp(double value);

    class Program

    {

    static void Main(string[] args)

    {

     

    Connection myConnection = new Connection();

    Display myDisplay = new Display();

    myConnection.MessageArrived += new MessageHandler(myDisplay.DisplayMessage);

    myConnection.Connect();

    Console.ReadKey();

    }

    }

    }

    第一行定义事件发布器

    第二行定义事件订阅器

    最后一行演示事件使用方法

    参考:http://www.runoob.com/csharp/csharp-event.html

  • 相关阅读:
    luogu P4779 【模板】单源最短路径(标准版)| dijkstra
    luogu P1160 队列安排 | 链式前向星
    luogu P1996 约瑟夫问题 | 链表
    luogu P3386 【模板】二分图匹配 | 匈牙利算法
    luogu P3366 【模板】最小生成树 | kruskal
    luogu P3378 【模板】堆
    luogu P3372 【模板】线段树 1
    luogu P1776 宝物筛选_NOI导刊2010提高(02) | 多重背包(二进制拆分)
    luogu P1616 疯狂的采药 | 完全背包
    luogu P1588 丢失的牛 | 宽搜
  • 原文地址:https://www.cnblogs.com/xyb930826/p/5293929.html
Copyright © 2011-2022 走看看