none
Dúvida qto Eventos - delegates - EventArgs - boas práticas d programacao RRS feed

  • Pergunta

  • Se eu qro criar um evento q seja disparado qdo um valor float é alterado, vou ter q criar um EventArg soh pra isso? Jah n tem EventArgs padroes? Acaba dando vontade de criar um delegate dessa forma:

    public delegate void DelegateSimples(float f);

    public event DelegateSimples floatXChanged; sendo q esse evento n segue as boas praticas...

    Sempre que eu crio um novo tipo de evento:

    public delegate void NovoEventHandler(object sender, MeuEventArgs e);

    Como vcs fazem nesse caso? Criam um delegate q faz o trabalho? Criam um evento seguindo as boas praticas, criando o novo eventhandler e o eventargs? Tem algo pronto jah?

     

     

    quinta-feira, 1 de julho de 2010 21:11

Respostas

  • Olha se for a partir do 3.5, vc so prescisa criar o EventArg... o problema de se usar (float f) é que vc ta usando um paramentro por referencia do tipo float...

    a ideia do eventargs é que vc usa propriedades.... (preferencialmente somente leitura...)

    public class FloatEventArgs: EventArg {
         public float Valor { get; private set; }
         
         public FloatEventArgs(float valor): base() {
             this.Valor = valor;
         }

    }

     

    o delegate nao é mais necessario... vc pode criar o evento assim:

    public event EventHandler<FloatEventArgs> FloatAlterado;


    por boas praticas vc ainda deve criar um metodo virtual (que possa ser dado overload nas classes filhos) para chamada do evento:

    protected virtual void OnFloatAlterado(FloatEventArgs e)  {
         if (this.FloatAlterado != null) this.FloarAlterado(this, e):

    }

     

    Alemo do mais usar um eventargs facilita em muito na parte de herança... ou no caso de eventos que vc pode usar pode passar um objeto no construtor e retornas apenas algumas propriedades somente leitura.... e varias outras coisas... que no momento parece que nao vai prescisar... mas no futuro prescisa... e ta mais facil de mexer se for assim...

     

     


    What would Brian Boitano do ?
    ((2B || !2B) is Question) ?
    • Sugerido como Resposta Ari C. RaimundoModerator sexta-feira, 2 de julho de 2010 03:14
    • Marcado como Resposta PedroDD sexta-feira, 2 de julho de 2010 20:03
    sexta-feira, 2 de julho de 2010 01:07
    Moderador
  • Deusiro,

    Concordo com a resposta do Rui e só complementando, como você mencionou "boas práticas", o ideal é que façamos a atribuição do evento a uma variável para então gerar o evento.

    O código do Rui ficaria assim:

    protected virtual void OnFloatAlterado(FloatEventArgs e)
    {
        var floatAlterado = this.FloatAlterado;
        if (floatAlterado != null)
           floatAlterado(this, e):
    }

    Porque criar a variável? Bom, Se você estiver em um ambiente multithreading é possível que o handler do evento possa não ser nulo no momento da comparação e uma outra thread deixá-lo como nulo quando este for utilizado na thread principal, gerando uma exceção do tipo NullReferenceException.

    Mais detalhes sobre isso você encontra no link abaixo.

    Events and Races
    http://blogs.msdn.com/b/ericlippert/archive/2009/04/29/events-and-races.aspx

    Att.

    Ari C. Raimundo
    MCAD, MCTS
    http://araimundo.blogspot.com  

    • Marcado como Resposta PedroDD sexta-feira, 2 de julho de 2010 20:03
    sexta-feira, 2 de julho de 2010 03:25
    Moderador

Todas as Respostas

  • Olha se for a partir do 3.5, vc so prescisa criar o EventArg... o problema de se usar (float f) é que vc ta usando um paramentro por referencia do tipo float...

    a ideia do eventargs é que vc usa propriedades.... (preferencialmente somente leitura...)

    public class FloatEventArgs: EventArg {
         public float Valor { get; private set; }
         
         public FloatEventArgs(float valor): base() {
             this.Valor = valor;
         }

    }

     

    o delegate nao é mais necessario... vc pode criar o evento assim:

    public event EventHandler<FloatEventArgs> FloatAlterado;


    por boas praticas vc ainda deve criar um metodo virtual (que possa ser dado overload nas classes filhos) para chamada do evento:

    protected virtual void OnFloatAlterado(FloatEventArgs e)  {
         if (this.FloatAlterado != null) this.FloarAlterado(this, e):

    }

     

    Alemo do mais usar um eventargs facilita em muito na parte de herança... ou no caso de eventos que vc pode usar pode passar um objeto no construtor e retornas apenas algumas propriedades somente leitura.... e varias outras coisas... que no momento parece que nao vai prescisar... mas no futuro prescisa... e ta mais facil de mexer se for assim...

     

     


    What would Brian Boitano do ?
    ((2B || !2B) is Question) ?
    • Sugerido como Resposta Ari C. RaimundoModerator sexta-feira, 2 de julho de 2010 03:14
    • Marcado como Resposta PedroDD sexta-feira, 2 de julho de 2010 20:03
    sexta-feira, 2 de julho de 2010 01:07
    Moderador
  • Hi,

    Amigo, em geral eu uso assim :

    public class MyEventArgs : EventArgs
    {
      public float Args { get; set; }
      public MyEventArgs() : base() { }
    }
    
    public delegate void MyEventHandler(object sender, MyEventArgs e);
    
    private event MyEventHandler myEvent;
    
    public event MyEventHandler MyEvent
    {
      add { myEvent = (MyEventHandler)Delegate.Combine(myEvent, value); }
      remove { myEvent = (MyEventHandler)Delegate.Remove(myEvent, value); }
    }
    
    private void CallMyEvent(float arg)
    {
      if (myEvent != null)
      {
        MyEventArgs e = new MyEventArgs();
        e.Args = arg;
        myEvent.Invoke(this, e);
      }
    }

    Att,


    Adriel Codeco Silva
    Email: adriel.silva@uppercase.com.br
    MSN: adrielcodeco@hotmail.com
    Blog: adrielcodeco.wordpress.com
    Uppercase – www.uppercase.com.br

    R. Primeiro de Março, 661 – Centro Barra Bonita - SP - CEP 17340-000
    sexta-feira, 2 de julho de 2010 02:37
    Moderador
  • Deusiro,

    Concordo com a resposta do Rui e só complementando, como você mencionou "boas práticas", o ideal é que façamos a atribuição do evento a uma variável para então gerar o evento.

    O código do Rui ficaria assim:

    protected virtual void OnFloatAlterado(FloatEventArgs e)
    {
        var floatAlterado = this.FloatAlterado;
        if (floatAlterado != null)
           floatAlterado(this, e):
    }

    Porque criar a variável? Bom, Se você estiver em um ambiente multithreading é possível que o handler do evento possa não ser nulo no momento da comparação e uma outra thread deixá-lo como nulo quando este for utilizado na thread principal, gerando uma exceção do tipo NullReferenceException.

    Mais detalhes sobre isso você encontra no link abaixo.

    Events and Races
    http://blogs.msdn.com/b/ericlippert/archive/2009/04/29/events-and-races.aspx

    Att.

    Ari C. Raimundo
    MCAD, MCTS
    http://araimundo.blogspot.com  

    • Marcado como Resposta PedroDD sexta-feira, 2 de julho de 2010 20:03
    sexta-feira, 2 de julho de 2010 03:25
    Moderador
  • public class FloatEventArgs: EventArg {
         public float Valor { get; private set; }
         
         public FloatEventArgs(float valor): base() {    

    Obrigado pela resposta!

    Pra que serve o :base() ?
    sexta-feira, 2 de julho de 2010 20:10
  • public class FloatEventArgs: EventArg {
         public float Valor { get; private set; }
         
         public FloatEventArgs(float valor): base() {    

    Obrigado pela resposta!

    Pra que serve o :base() ?

     

    O base se refere sempre a classe pai.... apesar de ja sabermos que atualmente o constructor da classe EventArgs no momento não implementa nada... pode ser que um dia tenha alguma implementação... colocando o :base() na frente do constructor da classe filho faz com que primeiro execute o constructor da classe pai e só depois o da classe filho:

    Por exemplo

    // Classe pai:
    public class Pai {
         public string Nome {get; set;}
         public string Sobrenome {get; set;}
         public string FullName { get { return Nome +  " " + Sobrenome; }

         public Pai() {
              this.Nome = "Fulano";
              this.Sobrenome = "de Tal";
         }
    }

    // Sem usar o base no Filho:
    public class Filho : Pai {
          public Filho() { 
               this.Nome = "Junior";
          }
    }

    se vc nesse ponto fizer:
    var filho = new Filho();
    // aqui a propriedade filho.FullName é igual a "Junior ", pois Sobrenome não teve valor atribuido e vale null

    // Usando o base no Filho:
    public class Filho : Pai {
          public Filho(): base() { 
               this.Nome = "Junior";
          }
    }

    var filho = new Filho();
    // aqui a propriedade filho.FullName é igual a "Junior de Tal", pois como foi executado primeiro o constructor de Pai, foi atribuido o valor a sobrenome

     


    Ari C. Raimundo

    Ari..... CARAMBA MEU !!!!!!!!!! Essa eu realmente não sabia.... sinceramente nunca tinha visto ninguem fazer desse jeito... mas faz todo sentido isso... muito bom mesmo valeu !!!!!!!!!!

     


    What would Brian Boitano do ?
    ((2B || !2B) is Question) ?
    sábado, 3 de julho de 2010 17:41
    Moderador