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


    委托

    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:
    ");
                OnBoilerEventLog("Temparature " + t + "
    Pressure: " + p);
                OnBoilerEventLog("
    Message: " + 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
  • 相关阅读:
    ssh免密登录
    jdk安装
    jq选择器
    使用<button></button>标签
    mysql连接字符串
    如何把maven项目转成web项目
    pl/sql连接远程oracle
    Oracle 存储过程
    SQL Server存储过程
    MySQL存储过程
  • 原文地址:https://www.cnblogs.com/asahiLikka/p/11644393.html
Copyright © 2020-2023  润新知