目录

标准事件写法(EventHandler + EventArgs)

标准事件写法:EventHandler / EventArgs

简单用法

public event Action OnClick;

但在正式项目中,事件一般会写成这样:

public event EventHandler<UserChangedEventArgs> UserChanged;

这个标准写法包含两部分:

1)EventHandler 是什么?

EventHandler 是微软提供的委托类型,用于事件:

public delegate void EventHandler(object sender, EventArgs e);
  • sender = 事件触发者(一般用 this)
  • e = 事件携带的数据(继承自 EventArgs)

可以理解为:

EventHandler = 带2个参数的委托,用于事件。

EventHandler

带自定义参数时,用泛型版本:

public delegate void EventHandler<TEventArgs>(object sender, TEventArgs e);

例如:

public event EventHandler<UserChangedEventArgs> UserChanged;

2)事件数据类:EventArgs

事件一般需要传递一些参数(比如当前用户、时间、状态等)。
这些参数使用一个类封装,继承自 EventArgs

public class UserChangedEventArgs : EventArgs
{
    public string UserName { get; set; }
    public int UserId { get; set; }

    public UserChangedEventArgs(string name, int id)
    {
        UserName = name;
        UserId = id;
    }
}

看到 EventArgs,就知道它是事件的数据包。

3)标准事件定义

public event EventHandler<UserChangedEventArgs>? UserChanged;

这是企业项目事件最常见写法之一。

4)触发事件(只允许类内部触发)

protected virtual void OnUserChanged(string name, int id)
{
    UserChanged?.Invoke(this, new UserChangedEventArgs(name, id));
}

这里:

  • this = 触发事件的对象
  • new UserChangedEventArgs(name, id) = 携带数据

5)订阅事件

外部:

userService.UserChanged += OnUserChanged;

void OnUserChanged(object sender, UserChangedEventArgs e)
{
    Console.WriteLine($"用户变了: {e.UserName}, ID={e.UserId}");
}

完整示例

① 定义事件 + EventArgs

public class UserService
{
    public event EventHandler<UserChangedEventArgs>? UserChanged;

    public void ChangeUser(string name, int id)
    {
        Console.WriteLine("更换用户...");
        OnUserChanged(name, id);
    }

    protected virtual void OnUserChanged(string name, int id)
    {
        UserChanged?.Invoke(this, new UserChangedEventArgs(name, id));
    }
}

② 定义事件参数

public class UserChangedEventArgs : EventArgs
{
    public string UserName { get; }
    public int UserId { get; }

    public UserChangedEventArgs(string name, int id)
    {
        UserName = name;
        UserId = id;
    }
}

③ 订阅 + 响应事件

var service = new UserService();

service.UserChanged += (sender, e) =>
{
    Console.WriteLine($"当前用户变更为:{e.UserName}, ID={e.UserId}");
};

service.ChangeUser("张三", 1001);

【总结】

这就是正规事件写法,格式固定:

1)定义 EventArgs 类型

class XxxEventArgs : EventArgs { ... }

2)定义事件

public event EventHandler<XxxEventArgs> XxxHappened;

3)触发事件(只能类内部)

XxxHappened?.Invoke(this, new XxxEventArgs());

4)外部订阅

obj.XxxHappened += Handler;