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#类和方法,如Console
。System.IO
命名空间包含了用于文件操作的类,如FileStream
和StreamWriter
。
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
的类,它有两个私有字段temp
和pressure
,分别表示锅炉的温度和压力。Boiler
构造函数用于初始化这两个字段。getTemp
和getPressure
方法用于获取温度和压力的值。
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
和一个事件BoilerEventLog
。LogProcess
方法创建了一个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#事件的几个关键点:
-
委托(Delegates):事件的基础是委托。委托定义了一组具有相同签名和返回类型的方法的容器。例如,一个委托可以指向多个方法,当事件发生时,这些方法会被依次调用。
-
事件声明:在C#中,事件是通过在类或结构体中声明一个委托类型的成员,并使用
event
关键字来完成的。例如: -
事件订阅:其他类可以通过+=操作符来订阅事件,这意味着它们想要在事件发生时接收通知。例如:
-
事件触发:在包含事件的类中,你可以通过调用事件来触发它,这会导致所有订阅了该事件的方法被调用。
-
事件取消订阅:使用-=操作符可以从事件的订阅者列表中移除一个方法,这样当事件被触发时,该方法就不会再被调用。
-
事件安全性:由于事件只能在声明它们的类中被触发,因此它们提供了一定程度的安全性,防止外部代码随意触发事件。
理解C#事件的关键在于理解它们是如何基于委托工作的,以及如何在类之间进行通信。事件提供了一种松耦合的方式,使得对象可以在不直接引用彼此的情况下进行交互。这种模式在图形用户界面(GUI)编程、多线程编程以及其他需要异步通知的场景中非常有用。