欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

C#事件和委托(C#学习笔记03)

程序员文章站 2023-11-25 14:36:22
委托 1. C# 中的委托类似于 C 或 C++ 中指向函数的指针。委托表示引用某个方法的引用类型变量,运行时可以更改引用对象。 2. 特别地,委托可以用于处理事件或回调函数。并且,所有的委托类都是从 System.Delegate 类继承而来。 声明委托的语法规则:(被委托所引用的方法需有相同的参 ......

委托

1. c# 中的委托类似于 c 或 c++ 中指向函数的指针。委托表示引用某个方法的引用类型变量,运行时可以更改引用对象。
2. 特别地,委托可以用于处理事件或回调函数。并且,所有的委托类都是从 system.delegate 类继承而来。

声明委托的语法规则:(被委托所引用的方法需有相同的参数和返回值)

delegate <return type> <delegate-name> <parameter list>

 

一个委托使用示例:

using system;

public delegate void mydelegate(string str);                //创建委托实例

namespace delegate
{
    class textmethods

    {
        public static void method1(string str)
        {
            console.writeline("这是方法1,{0}",str);
        }

        public static void method2(string str)

        {
            console.writeline("这是方法2,{0}",str);
        }

        public static void method3(string str)
        {
            console.writeline("这是方法3,{0}", str);
        }
    }
    class program
    {
        static void main(string[] args)
        {
            mydelegate d1, d2, d3;                               //定义委托变量

            d1 = textmethods.method1;

            d2 = textmethods.method2;

            d3 = textmethods.method3;

            d1("1");                                             //调用委托实例

            d2("2");

            d3("3");

            console.writeline("");

            mydelegate d4;

            d4 = textmethods.method1;

            d4 += textmethods.method2;                          //添加实例

            d4 += textmethods.method3;

            d4("4");

            console.writeline("");

            d4 -= textmethods.method3;                          //移除实例

            d4("5");

            console.writeline("");
        }
    }
}

 

事件

事件是应用程序在执行过程中所关注的一些动作,但这些动作发生时,程序需要对其做出响应。事件的概念比较广泛,所有程序需要进行响应处理的动作都可以称为事件。如鼠标单击、键盘输入、计时器消息...

事件基于委托,为委托提供了一种发布/订阅机制,在.net架构内外都可以看到事件。在windows应用程序中,button类提供了click事件。这类事件就是委托,触发click事件调用的处理程序需要得到定义,而其参数由委托类型定义。

事件机制是以消息为基础的,当特定的动作发生后会产生相应的消息,关注该事件的应用程序收到事件发生的消息,就会开始指定处理过程。

示例:

参考自:[w3cschool] https://www.w3cschool.cn/wkcsharp/yvoj1nvx.html"%3ehttps://www.w3cschool.cn/wkcsharp/yvoj1nvx.html%3c/a%3e

该示例为一个简单的应用程序,该程序用于热水锅炉系统故障排除。当维修工程师检查锅炉时,锅炉的温度、压力以及工程师所写的备注都会被自动记录到一个日志文件中。
示例中可以看出,在主函数中,创建了事件发布器类(delegateboilerevent),并将一个写入文档的(订阅器)和一个控制台输出函数添加进事件示例中。在执行触发器类中的记录过程函数(logprocess() )时,就会调用所有添加进事件的函数实例。

 

using system;
using system.io;

namespace boilereventappl
{
    // boiler 类
    class boiler
    {
        private int temp;                             //锅炉温度
        private int pressure;                         //锅炉压力
        public boiler(int t, int p)                   //构造函数
        {
            temp = t;
            pressure = p;
        }

        public int gettemp()
        {
            return temp;
        }

        public int getpressure()
        {
            return pressure;
        }
    }

    // 事件发布器
    class delegateboilerevent
    {
        public delegate void boilerloghandler(string status);            //声明委托

        // 基于上述委托定义事件
        public event boilerloghandler boilereventlog;

        public void logprocess()                                         //记录过程
        {
            string remarks = "o. k";
            boiler b = new boiler(100, 12);
            int t = b.gettemp();
            int p = b.getpressure();
            if (t > 150 || t < 80 || p < 12 || p > 15)                  
            {
                remarks = "need maintenance";
            }
            onboilereventlog("logging info:\n");
            onboilereventlog("temparature " + t + "\npressure: " + p);
            onboilereventlog("\nmessage: " + remarks);
        }

        protected void onboilereventlog(string message)      //函数在发布器类中,当要进行发布时,就触发事件boilereventlog所添加的实例
        {
            if (boilereventlog != null)                                                         
            {
                boilereventlog(message);
            }
        }
    }

    // 该类保留写入日志文件的条款
    class boilerinfologger
    {
        filestream fs;
        streamwriter sw;
        public boilerinfologger(string filename)
        {
            fs = new filestream(filename, filemode.append, fileaccess.write);
            sw = new streamwriter(fs);
        }

        public void logger(string info)     //信息写入文档
        {
            sw.writeline(info);
        }

        public void close()
        {
            sw.close();
            fs.close();
        }
    }

    // 事件订阅器
    public class recordboilerinfo
    {
        static void logger(string info)           //控制台输出信息
        {
            console.writeline(info);
        }//end of logger

        static void main(string[] args)
        {
            boilerinfologger filelog = new boilerinfologger("‪boiler.txt");  //打开日志文件
            delegateboilerevent boilerevent = new delegateboilerevent();    //实例化delegateboilerevent类,事件发布器
            boilerevent.boilereventlog += new
            delegateboilerevent.boilerloghandler(logger);                   //boilerevent.boilereventlog为委托的实例,将logger添加进委托
            boilerevent.boilereventlog += new
            delegateboilerevent.boilerloghandler(filelog.logger);           //filelog是boilerinfologger类的实例化,将其中的logger函数添加进委托
            boilerevent.logprocess();                                       //执行logproccess函数
            filelog.close();
        }//end of main

    }//end of recordboilerinfo
}

 

 

执行结果:

logging info:

temparature 100
pressure: 12

message: o. k