Ainda não tem acesso? Estude com a gente! Matricule-se
Ainda não tem acesso? Estude com a gente! Matricule-se

Solucionado (ver solução)

Nomenclatura de eventos: fazer casting do sender ou enviar no Args ?

Bom dia, Eu estou com duvida de como devo enviar os parâmetros de um evento. Digamos que eu tenha um EventHandler (ou seja, os parâmetros são object sender e EventArgs e) e eu queira obter conteúdos que vem da classe que notificou o evento, a duvida é: eu faço casting do sender para obter a classe, ou eu crio uma nova classe que herda de EventArgs para eu acessar no segundo parâmetro ?

A situação é essa: 1- Toda vez que um jogador morrer, ele disparará OnPlayerDeath. 2- A classe Achievements deve ser notificada pela primeira morte do jogador, pelo método FirstDeath.

Dúvida: 1- Qual seria a melhor forma, seguindo nomenclatura para fazer tal? esse código está valido? 2- Se eu for pegar o objeto, eu faço apenas casting do sender ou envio pelo Args (que eu teria de criar uma classe que herda de EventArgs) ?

Player player = sender as Player;

3- Eu sou obrigado, pela nomenclatura, de ter um EventHandler como delegate de um evento?

Código:

using System;

public class Program
{
    public static void Main()
    {
        Player jogador = new Player("IntelGraphics");
        jogador.PlayerDeath += new Achievements().FirstDeath;

        Console.ReadKey();
    }
}

public class Player 
{
    public event EventHandler PlayerDeath;

    public string name { get; }

    public Player (string name)
    {
        this.name = name;
    }

    protected virtual void OnPlayerDeath()
    {
        if (PlayerDeath != null)
            PlayerDeath(this, EventArgs.Empty);
    }

    public void kill ()
    {
        OnPlayerDeath();
    }
}

public class Achievements 
{
    public event EventHandler<Player> PlayerAcquiredAchievement;

    protected virtual void OnPlayerAcquiredAchievement(Player player)
    {
        if (PlayerAcquiredAchievement != null)
            PlayerAcquiredAchievement(this, player);
    }

    public void FirstDeath(object sender, EventArgs e)
    {
        Player player = sender as Player; //<----------------------------------------------------
        Console.WriteLine("Você recebeu uma conquista: primeira morte !");

        OnPlayerAcquiredAchievement(player);
    }
}

public class AchievementsEventHandler : EventArgs
{
    public Player player {  get; }

    public AchievementsEventHandler (Player player)
    {
        this.player = player;
    }
}
1 resposta
solução

Oi Victor, tudo bem?

1- Qual seria a melhor forma, seguindo nomenclatura para fazer tal? esse código está valido?

Eu deixaria a classe Achievements como uma dependência da classe Player, e pensaria até mesmo em absorver os membros de Achievements e colocá-los dentro da classe Player. Talvez você esteja pensando em alguma expansão dessa classe no futuro, mas no momento não estou vendo muita utilidade na classe Achievements. Acho que ela só está deixando seu código mais complexo.

2- Se eu for pegar o objeto, eu faço apenas casting do sender ou envio pelo Args (que eu teria de criar uma classe que herda de EventArgs) ?

Você só precisa derivar a classe EventArgs em subclasse se precisar passar algum valor. Mas se a ideia é somente notificar "o jogador (sender) morreu", você não precisar criar uma subclasse para EventArgs.

3- Eu sou obrigado, pela nomenclatura, de ter um EventHandler como delegate de um evento?

Sim, é obrigatório usar um EventHandler, dessa forma:

event EventHandler Nome_do_Evento

Note que você também pode usar EventHandler tipada:

event EventHandler<TipoDoObjeto> Nome_do_Evento