C# delegate与event,委托与事件

文章目录

  • 博主写作不容易,孩子需要您鼓励
  • 万水千山总是情 , 先点个赞行不行

委托和事件是C#中两个比较复杂的概念,这篇文章介绍两个概念与基本用法,让大家理解C#中的事件处理机制。

委托

委托也叫代理,就是把事情交付给别人去办,如代购。C#中如果将一个方法委托给一个对象,这个对象就可以全权代理这个方法的执行。
使用委托时首先要定义委托,声明委托能代理什么类型的方法。

  • 语法格式如下:
  • <访问修饰符> delegate 返回类型 委托名();
    

    从上边的语法格式可以看出,定义委托与定义方法类似。
    委托没有具体实现,委托能够代表什么样的方法由它的返回类型和参数列表决定。如果定义如下的委托:

    public delegate void stuDelegate(string name);
    

    那么使用stuDelegate委托代表的只可以是没有返回值,且参数为一个字符串的方法。
    定义了委托之后要使用委托,首先要实例化委托。实例化委托就是将其指向某个方法,即调用委托的构造函数,并将相关联的方法作为参数传递。然后通过调用委托,执行相关方法的代码,实现委托。

    示例

    使用委托对数组元素按降序排列

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace test
    {
        class Program
        {
            public delegate bool ShortDelegate(int[] x);
            static void Main(string[] args)
            {
                int[] arr = new int[] { 8, 4, 5, 6, 2, 1, 3, 7, 9, 0 };
                Console.WriteLine("未排序前数组序列为:");
                foreach (int i in arr)
                {
                    Console.Write("{0},", i);
                }
    
                ShortDelegate MyDelegate;//声明委托变量
                MyDelegate = new ShortDelegate(ArrayShort.SortArray);//实例化委托
    
                MyDelegate(arr);//调用委托排序
                Console.WriteLine("\n排序后数组序列为:");
                foreach (int i in arr)
                {
                    Console.Write("{0},", i);
                }
                Console.ReadKey();
    
                
            }
        }
        class ArrayShort
        {
            public static bool SortArray(int[] Array)
            { //定义方法SortArray用于按照降序排列
                for (int i = Array.GetUpperBound(0); i >= 0; i--)//循环从后向前分别取出数组中的一个元素
                {//冒泡排序,将数值小的元素移到后面,直到所有的元素按照降序排列
                    for (int j = 0; j <= i; j++)
                    {
                        if (Array[j] <= Array[i])
                        {
                            Swap(ref Array[j], ref Array[i]);//交换两个元素位置
                        }
                    }
                }
                return true;
            }
            static void Swap(ref int x,ref int y)//交换两个数
            {
                int z = x;
                x = y;
                y = z;
            }
        }
    
    }
    

    运行结果:
    在这里插入图片描述

    事件

    事件是C#中的一个高级概念,是操作发生时允许执行特定应用程序的代码的机制。事件要么在相关联的操作发生前发生,要么在操作发生后发生。例如,当用户单击窗口中的按钮时,将引发一个事后事件,以允许执行特定于应用程序的方法。类或对象可以通过事件向其他类或对象通知发生的相关事情。发送事件的类成为发行者,接受事件的类成为订阅者。在典型的C#Windows窗体或者web应用开发中,可以订阅由控件引发的事件。

  • 在C#类中定义和使用事件一般有下面几个步骤。
  • 1、在类中声明关于事件的委托。
  • public delegate void 事件类型名称(object sender,EventArgs e);
    

    在事件类型名称建议使用EventHandler结尾。如果想自定义事件的参数EventArgs,可以用EventArgs类派生自己的事件参数类,也可以没有参数。

  • 2、在类中声明事件,使用步骤1的委托作为事件的类型。
  • public event 事件类型的名称 事件名称;
    
  • 3、在类中需要引发事件的方法中,编写引发事件的方法。
  • 事件名称(this, new EventArgs());
    

    或者

    if(事件名称!=null) 事件名称(this, new EventArgs());
    
  • 4、订阅事件,当事件发生时通知订户。
  • 带有事件的类实例.事件名称+=new 事件名称(事件处理方法名称);
    
  • 5、编写事件处理方法。
  • public void 事件处理方法名称(object sender,EventArgs e)
    {
    //添加事件处理代码
    }
    
  • 6、在适当的条件下触发事件,即需要调用步骤3中的引发事件的方法。
  • 实例

    假设设计一个高档热水器,通电加热超过97℃时,扬声器会进行提示现在温度,显示器提示水快烧开了。

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace test
    {
        class Program
        {
            public delegate bool ShortDelegate(int[] x);
            static void Main(string[] args)
            {
                Heater heater = new Heater();
                Alarm alarm = new Alarm();
    
                heater.BoilEvent += alarm.MakeAlert;
                heater.BoilEvent += Display.ShowMsg;
                heater.BoilWater();
                Console.ReadKey();
    
                
            }
        }
        public class Heater
        {
            private int temperature;//水温
            public delegate void BoilHandle(int x);//声明关于事件的委托
            public event BoilHandle BoilEvent;//声明水要烧开的事件
            public void BoilWater()
            { //烧水的方法
                for (int i = 0; i <= 100; i++)
                {
                    temperature = i;
                    if (temperature > 96)
                    {
                        if (BoilEvent != null)
                        {
                            BoilEvent(temperature);
                        }
                    }
                }
            }
    
        }
        public class Alarm
        {
            public void MakeAlert(int x)
            { //水开烧开的报警方法
                Console.WriteLine("Alarm:dididid,水已经{0}℃了",x);
            }
        }
        public class Display
        {
            public static void ShowMsg(int x)
            {
                Console.WriteLine("Display:水快开了,当前温度为:{0}℃",x);
            }
        }
    
    }
    

    运行结果:
    在这里插入图片描述

    ------------------------------------------------------------------------------------------
                                                  分割线
    ------------------------------------------------------------------------------------------
    
    • 博主简介:
    • 工业自动化上位机软件工程师、机器视觉算法工程师、运动控制算法工程师。目前从业于智能制造自动化行业。 博主邮箱:2296776525@qq.com
    • 帮忙点个赞吧。哈哈。
  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值