О, у меня была та же проблема.Я понял концепцию событий, потому что я интенсивно использовал их в JavaScript, но я просто не мог оправдать использование событий в приложении C #.Я имею в виду, я использовал сервер OnClick
и т. Д., Но я не мог понять, зачем мне использовать события где-либо еще.
На самом деле забавная история, потому что я усвоил ее нелегко, работая над своей игрой ORPG,Рассмотрим следующий код:
class Player
{
private int health;
public int Health
{
get
{
if (health <= 0)
{
Die();
}
return health;
}
set
{
health = value;
}
}
public void Die()
{
// OMG I DIED, Call bunch of other methods:
// RemoveFromMap();
// DropEquipment(); etc
}
}
Имеет смысл, верно?У игрока нет здоровья, поэтому я звоню Die()
.Затем метод Die делает все, что должен - убить игрока.
Мои проблемы начались, когда я захотел повторно использовать этот класс в приложении Server и Client моей игры ORPG.Довольно легко заметить, что метод Die()
должен выполнять разные вещи, в зависимости от того, где выполняется 'Kill' - на сервере он должен обновлять все виды различных данных - на клиенте он должен делать что-то с графикой.
Дополнительно - что, если бы я хотел, чтобы метод Die()
делал разные вещи, в зависимости от типа проигрывателя?После того, как все контролируемые пользователем игроки должны делать разные вещи, когда их убивают, по сравнению с игроками, контролируемыми компьютером / ИИ (NPC).
И вот, я был вынужден использовать события:
class Player
{
public event DieHandler Die;
public delegate void DieHandler(Player sender, EventArgs e);
public virtual void OnDie(EventArgs e)
{
if (Die != null)
Die(this, e);
}
private int health;
public int Health
{
get
{
if (health <= 0)
{
onDie(new EventArgs());
}
return health;
}
set
{
health = value;
}
}
}
Итеперь, когда я создаю нового игрока, я могу назначить любой метод для его DieHandler
:
Player player = new Player("Joe");
player.Die += Client.Players.PlayerDie;
Player npc = new Player("Cookie Monster");
npc.Die += Client.Npcs.NpcDie;
, где Client.Npcs.Die
и Client.Players.Die
- один из следующих:
public void NpcDie(Player sender, EventArgs e)
{
//who hoo, I can be implemented differently
//I can even check if sender.Health <= 0
}
public void PlayerDie(Player sender, EventArgs e)
{
}
Как вы можете видеть, теперь у нас есть гибкость, позволяющая присоединить любой «подходящий» метод к нашему обработчику Die.Мы отправляем объект Player в качестве атрибута отправителя и любой определенный EventArgs
в e.Мы можем использовать EventArgs
для отправки дополнительной информации, например - e.NameOfTheKiller
, e.LastHitAtTime
и т. Д. Лучше всего то, что вы можете определить свой собственный класс EventArgs
, чтобы вы могли отправлять дополнительную информацию, когда вы создаете событие.
Ух ты ... этот пост длинный.Я надеюсь, что вы получите это сейчас.
Опять же - используйте события везде, когда вы хотите «сообщить внешнему миру» о каком-то конкретном состоянии вашего объекта и соответствующим образом обработать это изменение.Это сделает ваш код более гибким и намного проще в обслуживании.