能说说C#事件如何使用吗?

在Microsoft的产品文档上这样来定义的事件:事件是一种使对象或类能够提供通知的成员。客户端可以通过提供事件处理程序为相应的事件添加可执行代码。设计和使用事件的全过程大概包括以下几个步骤:.

能说说C#事件如何使用吗?

下面我们来按照规范的步骤来展示一个通过控制台输出事件的使用示例:

① 定义一个控制台事件ConsoleEvent的参数类型ConsoleEventArgs

/// <summary>
/// 自定义一个事件参数类型
/// </summary>
public class ConsoleEventArgs : EventArgs
{
    // 控制台输出的消息
    private string message;
    public string Message
    {
        get
        {
            return message;
        }
    }
    public ConsoleEventArgs()
        : base()
    {
        this.message = string.Empty;
    }
    public ConsoleEventArgs(string message)
        : base()
    {
        this.message = message;
    }
}

② 定义一个控制台事件的管理者,在其中定义了事件类型的私有成员ConsoleEvent,并定义了事件的发送方法SendConsoleEvent

/// <summary>
/// 管理控制台,在输出前发送输出事件
/// </summary>
public class ConsoleManager
{
    // 定义控制台事件成员对象
    public event EventHandler<ConsoleEventArgs> ConsoleEvent;

    /// <summary>
    /// 控制台输出
    /// </summary>
    public void ConsoleOutput(string message)
    {
        // 发送事件
        ConsoleEventArgs args = new ConsoleEventArgs(message);
        SendConsoleEvent(args);
        // 输出消息
        Console.WriteLine(message);
    }
    /// <summary>
    /// 负责发送事件
    /// </summary>
    /// <param name="args">事件的参数</param>
    protected virtual void SendConsoleEvent(ConsoleEventArgs args)
    {
        // 定义一个临时的引用变量,确保多线程访问时不会发生问题
        EventHandler<ConsoleEventArgs> temp = ConsoleEvent;
        if (temp != null)
        {
            temp(this, args);
        }
    }
}

③ 定义了事件的订阅者Log,在其中通过控制台时间的管理类公开的事件成员订阅其输出事件ConsoleEvent

/// <summary>
/// 日志类型,负责订阅控制台输出事件
/// </summary>
public class Log
{
    // 日志文件
    private const string logFile = @"C:\TestLog.txt";
    public Log(ConsoleManager cm)
    {
        // 订阅控制台输出事件
        cm.ConsoleEvent += this.WriteLog;
    }
    /// <summary>
    /// 事件处理方法,注意参数固定模式
    /// </summary>
    /// <param name="sender">事件的发送者</param>
    /// <param name="args">事件的参数</param>
    private void WriteLog(object sender, EventArgs args)
    {
        // 文件不存在的话则创建新文件
        if (!File.Exists(logFile))
        {
            using (FileStream fs = File.Create(logFile)) { }
        }
        FileInfo fi = new FileInfo(logFile);
        using (StreamWriter sw = fi.AppendText())
        {
            ConsoleEventArgs cea = args as ConsoleEventArgs;
            sw.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "|" + sender.ToString() + "|" + cea.Message);
        }
    }
}

④ 在Main方法中进行测试:

public class Program
{
    public static void Main(string[] args)
{
        // 控制台事件管理者
        ConsoleManager cm = new ConsoleManager();
        // 控制台事件订阅者
        Log log = new Log(cm);

        cm.ConsoleOutput("测试控制台输出事件");
        cm.ConsoleOutput("测试控制台输出事件");
        cm.ConsoleOutput("测试控制台输出事件");

        Console.ReadKey();
    }
}

能说说C#事件如何使用吗?

当该程序执行时,ConsoleManager负责在控制台输出测试的字符串消息,与此同时,订阅了控制台输出事件的Log类对象会在指定的日志文件中写入这些字符串消息。可以看出,这是一个典型的观察者模式的应用,也可以说事件为观察者模式提供了便利的实现基础。