c#委托和事件

委托就是相同签名(参数)和返回值类型的有序方法列表
delegate void 名(参数);
名 委托变量 =new 名(添加的方法)–也可以不用new,直接方法

组合委托
多播委托(含有多个方法,连续调用)
(带ref引用参数的委托,参数值会被列表里的方法的返回值改变)

匿名方法初始化委托:委托类型 委托变量 =delegate() { PrintMessage();}
匿名方法可以捕获上一级的外部变量
再简化就是Lambda
委托类型 委托变量 =(int x) => { PrintMessage();}
委托类型 委托变量 = x => { return x+1;}
委托类型 委托变量 = x => x+1;

特殊的委托

delegate bool Function(int num);
        static Function IsEven = delegate (int num) { return num % 2 == 0; };
        //或者使用Func类型:static Func<int,bool> IsEven =delegate(int num){....}///int是代表输入的参数类型,bool是代表输出的值类型

事件——被简化的针对特殊用途的委托
public event 委托类型 事件名;(所以事件是成员,而不是类型)

  • 触发 raise
  • 发布者 publisher
  • 订阅者 subscriber
  • 事件处理程序 event handler [ EventHandler (object sender,EventArgs e) 是标准预定义类型,经常使用]
    sender是触发事件的对象的引用,EventArgs 是保存一些程序的状态信息

说的再多,不如看代码来的实际

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            PlayMusic p = new PlayMusic("mayang");
            //先注册事件
            p.Delplay += P_Delplay;
        }

        private static void P_Delplay(object sender, EventArgs e)
        {
            PlayMusic P = (PlayMusic)sender;
            Console.WriteLine(P.Name + "播放完毕");
        }
    }
    class PlayMusic
    {
        //先注册一个事件
        public event EventHandler Delplay;//用eventhandler类-事件响应基类,本质就是一个委托//参数有二

        public string Name { get; set; }
        public PlayMusic(string name)
        {
            this.Name = name;

        }
        public void PlaySong()
        {
            Console.WriteLine("播放" + this.Name);
            Thread.Sleep(3000);
            //启动事件,事件就是一个因果关系的联系,你打我我打你
            //事件本身就是一个委托(多播委托),为什么不直接用委托呢?
            //因为委托不安全,委托就像一个指针,使用没有什么限制,而事件给其中的委托加了一层壳,只有“因”结束才会引发事件
            //而且事件只有在类的内部才能调用
            if (Delplay != null)
            {
                EventArgs e = new EventArgs();
                Delplay(this, e);
            }
        }
    }
namespace 事件
{
    internal class KeyEventArgs : EventArgs
    //EventArgs是包含事件数据的类的基类,此类不包含事件数据,在事件引发时不向事件处理程序传递状态信息的事件会使用此类。
    //如果事件处理程序需要状态信息,则应用程序必须从此类派生一个类来保存数据。
    {
        private char keyChar;
        public KeyEventArgs(char keyChar) : base()
        {
            this.keyChar = keyChar;

        }
        public char KeyChar
        {
            get
            {
                return keyChar;
            }
        }
    }
    internal class KeyInputMonitor
    {
        // 创建一个委托,返回类型为void,两个参数
        public delegate void KeyDownHandler(object sender, KeyEventArgs e);
        // 将创建的委托和特定事件关联,在这里特定的事件为KeyDown
        public event KeyDownHandler KeyDown;

        public void Run()
        {
            bool finished = false;
            do
            {
                Console.WriteLine("Input a char");
                string response = Console.ReadLine();

                char responseChar = (response == "") ? ' ' : char.ToUpper(response[0]);
                switch (responseChar)
                {
                    case 'X':
                        finished = true;
                        break;
                    default:
                        // 得到按键信息的参数
                        KeyEventArgs keyEventArgs = new KeyEventArgs(responseChar);
                        // 触发事件,ta的参数和关联的委托要一致
                        KeyDown(this, keyEventArgs);
                        //事件交由KeyDownHandler这个委托来处理,委托指定事件处理方法去处理事件,这就是事件接收方的类的事情了
                        break;
                }
            } while (!finished);
        }
    }
    internal class EventReceiver
    {
        public EventReceiver(KeyInputMonitor monitor)
        {
            // 产生一个委托实例并添加到KeyInputMonitor产生的事件列表中
            monitor.KeyDown += new KeyInputMonitor.KeyDownHandler(this.OnKeyDown);
        }
        private void OnKeyDown(object sender, KeyEventArgs e)
        {
            // 真正的事件处理函数
            Console.WriteLine("Capture key: {0}", e.KeyChar);
        }
    }
    class 事件1
    {
        static void Main(string[] args)
        {
            // 实例化一个事件发送器
            KeyInputMonitor monitor = new KeyInputMonitor();
            // 实例化一个事件接收器
            EventReceiver eventReceiver = new EventReceiver(monitor);
            // 运行
            monitor.Run();
        }
    }
}

事件访问器:add(+=)和remove(-=)类似属性
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值