使用 events 的想法是为某些对象提供能力,该对象存储此事件(称为“发布者”)通知订阅此事件的其他一些对象(称为“订阅者”),发生了什么事。
您的示例可能会以“当某些用户加入时通知”的方式使用。它使用某种"Publisher-Subscriber pattern"。
所以,您有一些EventProgram 类,它是存储事件OnUserJoin 的“发布者”,每次用户加入时都会触发该事件(添加到List)。添加新用户后通过调用OnUserJoinEventHandler 提供事件触发。在调用它时,我们提供username 到UserJoinedEventArgs - 这是“发生了什么”的一种“细节”。 OnUserJoin?(和?)表示检查,有一些“订阅者”我们可以向谁“发送通知”。
public class EventProgram
{
private readonly List<string> users;
// Publishing event for "subscribers"
public event EventHandler<UserJoinedEventArgs> OnUserJoin;
public EventProgram()
{
users = new List<string>();
}
public void AddNewUser(string username)
{
// Adding new user
users.Add(username);
// And calling event to notify "subscribers" that we added provided user
OnUserJoin?.Invoke(this, new UserJoinedEventArgs { Username = username });
}
}
// Custom details for our event
public class UserJoinedEventArgs
{
public string Username { get; set; }
// and other details you wish to provide about joined user
}
将它用作“订阅者”是创建处理程序(例如HandleUserJoin),它将“接受来自“发布者”类的通知,并使用来自UserJoinedEventArgs 的接受的详细信息做一些事情。
void Main(string[] args = default)
{
EventProgram eventProgram = new EventProgram();
// "Subscribing" to "publisher"'s event with `HandleUserJoin` handler
eventProgram.OnUserJoin += HandleUserJoin;
// Adding new user
eventProgram.AddNewUser("Mr.Wadile");
}
// This handler is actually "subscriber", which waits for notifications
// from "publisher"'s OnUserJoin event with details, provided
// as UserJoinedEventArgs
private void HandleUserJoin(object sender, UserJoinedEventArgs args)
{
Console.WriteLine("Welcome, " + args.Username);
}
结果,每次我们使用.AddNewUser("Some Username") 添加新用户时-“发布者”EventProgram 将通过OnUserJoin 事件通知我们,当我们在HandleUserJoin 中“接受”此通知时-我们打印欢迎消息。
回答有关+= 运算符的问题 - 这实际上是“订阅”过程,当您“订阅”HandleUserJoin 方法以接收来自OnUserJoin 事件的通知时(在本例中)。
委托通常是指向某些方法的“指针”,这些方法与委托签名相匹配。根据上面的示例,您可以使用委托来组合不同的操作并将它们全部称为一个:
public class EventProgram
{
private readonly List<string> users;
// Delegate declaration with "void (string)" signature
public delegate void JoinUser(string username);
// A field of delegate type, that will be used to call from other classes
public JoinUser JoinNewUser;
public EventProgram()
{
users = new List<string>();
// Combining different actions with User into one delegate
// First - assigning with "=" (+= can be used too)
JoinNewUser = AddUserToDatabase;
// Next - appending with "+="
JoinNewUser += WelcomeUser;
JoinNewUser += SendWelcomeGiftToUser;
}
// Matches to delegate signature "void (string)"
private void AddUserToDatabase(string username)
{
users.Add(username);
Console.WriteLine("New user \"" + username + "\" added to database!");
}
// Matches to delegate signature "void (string)"
private void WelcomeUser(string username) =>
Console.WriteLine("Welcome, " + username);
// Matches to delegate signature "void (string)"
private void SendWelcomeGiftToUser(string username) =>
Console.WriteLine(username + ", we sending you 100$ as a welcome gift!");
}
所以在创建EventProgram 的实例后,我们只需在其他类中调用JoinNewUser,所有3 个动作都将被委托调用:
void Main(string[] args = default)
{
EventProgram eventProgram = new EventProgram();
eventProgram.JoinNewUser("Mr.Wadile");
}
所以它看起来像:
+= 运算符通常在订阅事件时使用,因为= 运算符将替换“委托堆栈”并且只执行最后一个委托。例如,在前面的例子中:
JoinNewUser = AddUserToDatabase;
JoinNewUser = WelcomeUser;
JoinNewUser = SendWelcomeGiftToUser;
只会输出SendWelcomeGiftToUser 委托,而不是预期的三个委托/函数/方法:
Wadile 先生,我们送您 100 美元作为欢迎礼物