人生低谷来撸C#--017事件(Event)

1、先上一段关于事件的代码

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)
      {
         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("e:\\boiler.txt");
         DelegateBoilerEvent boilerEvent = new DelegateBoilerEvent();
         boilerEvent.BoilerEventLog += new 
         DelegateBoilerEvent.BoilerLogHandler(Logger);
         boilerEvent.BoilerEventLog += new 
         DelegateBoilerEvent.BoilerLogHandler(filelog.Logger);
         boilerEvent.LogProcess();
         Console.ReadLine();
         filelog.Close();
      }//end of main

   }//end of RecordBoilerInfo
}

2、我们让AI逐行解释一下

using System;
using System.IO;

这里好理解,这两行代码引入了必要的命名空间。System命名空间包含了基本的C#类和方法,如ConsoleSystem.IO命名空间包含了用于文件操作的类,如FileStreamStreamWriter

namespace BoilerEventAppl 
{

这一行定义了一个命名空间BoilerEventAppl,用于组织代码。

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;
    }
}

这部分定义了一个名为Boiler的类,它有两个私有字段temppressure,分别表示锅炉的温度和压力。Boiler构造函数用于初始化这两个字段。getTempgetPressure方法用于获取温度和压力的值。

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("Temperature: " + t + "\nPressure: " + p);
        OnBoilerEventLog("\nMessage: " + remarks);
    }
 
    protected void OnBoilerEventLog(string message)
    {
        if (BoilerEventLog != null)
        {
            BoilerEventLog(message);
        }
    }
}

这部分定义了一个名为DelegateBoilerEvent的类,它有一个委托BoilerLogHandler和一个事件BoilerEventLogLogProcess方法创建了一个Boiler对象,并检查其温度和压力是否在指定范围内。然后,它调用OnBoilerEventLog方法来触发事件,将锅炉的状态信息和备注传递给订阅者。

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();
    }
}

这部分定义了一个名为BoilerInfoLogger的类,它负责将锅炉的状态信息写入到日志文件中。Logger方法用于写入信息,Close方法用于关闭文件流。

class RecordBoilerInfo 
{
    static void Logger(string info)
    {
        Console.WriteLine(info);
    }
 
    static void Main(string[] args)
    {
        BoilerInfoLogger filelog = new BoilerInfoLogger("e:\\boiler.txt");
        DelegateBoilerEvent boilerEvent = new DelegateBoilerEvent();
        boilerEvent.BoilerEventLog += new DelegateBoilerEvent.BoilerLogHandler(Logger);
        boilerEvent.BoilerEventLog += new DelegateBoilerEvent.BoilerLogHandler(filelog.Logger);
        boilerEvent.LogProcess();
        Console.ReadLine();
        filelog.Close();
    }
}

这部分定义了一个名为RecordBoilerInfo的类,它订阅了BoilerEventLog事件,并实现了两个事件处理方法,一个将信息输出到控制台,另一个将信息写入到日志文件中。Main方法是程序的入口点,它创建了一个BoilerInfoLogger对象和一个DelegateBoilerEvent对象,并订阅了事件。然后,它调用LogProcess方法来触发事件,从而将锅炉状态信息输出到控制台和日志文件中。

3、这下明白什么是事件了吗

在C#中,事件(Events)是一种使对象能够提供通知的成员。当某个行为发生时,比如按钮被点击或者数据模型发生了变化,事件允许对象发送通知给其他对象,这样其他对象就可以响应这个行为。事件是基于委托(Delegates)的,委托可以看作是一种类型安全的函数指针,而事件则是委托的一个“受限版本”,它只能在类内部触发,而在类外部只能订阅(Subscribe)或取消订阅(Unsubscribe)。

以下是理解C#事件的几个关键点:

  1. 委托(Delegates):事件的基础是委托。委托定义了一组具有相同签名和返回类型的方法的容器。例如,一个委托可以指向多个方法,当事件发生时,这些方法会被依次调用。

  2. 事件声明:在C#中,事件是通过在类或结构体中声明一个委托类型的成员,并使用event关键字来完成的。例如:

     
  3. 事件订阅:其他类可以通过+=操作符来订阅事件,这意味着它们想要在事件发生时接收通知。例如:

  4. 事件触发:在包含事件的类中,你可以通过调用事件来触发它,这会导致所有订阅了该事件的方法被调用。

  5. 事件取消订阅:使用-=操作符可以从事件的订阅者列表中移除一个方法,这样当事件被触发时,该方法就不会再被调用。

  6. 事件安全性:由于事件只能在声明它们的类中被触发,因此它们提供了一定程度的安全性,防止外部代码随意触发事件。

理解C#事件的关键在于理解它们是如何基于委托工作的,以及如何在类之间进行通信。事件提供了一种松耦合的方式,使得对象可以在不直接引用彼此的情况下进行交互。这种模式在图形用户界面(GUI)编程、多线程编程以及其他需要异步通知的场景中非常有用。

  • 20
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值