Condividi tramite


Ca1003: Utilizzare istanze di gestori eventi generici

TypeName

UseGenericEventHandlerInstances

CheckId

CA1003

Category

Microsoft.Design

Breaking Change

Breaking

Causa

Un tipo contiene un delegato che restituisce un tipo void, la cui firma contiene due parametri (il primo è un oggetto e il secondo un tipo assegnabile a EventArgs) e l'assembly che lo contiene è destinato a .NET Framework 2.0.

Descrizione della regola

Prima di .NET Framework 2.0, per passare informazioni personalizzate al gestore eventi era necessario dichiarare un nuovo delegato che specificasse una classe derivata dalla classe System.EventArgs. In .NET Framework 2.0, con l'introduzione del delegato System.EventHandler<TEventArgs>, non è più necessario. Questo delegato generico consente di utilizzare con il gestore dell'evento tutte le classi derivate da EventArgs.

Come correggere le violazioni

Per correggere una violazione di questa regola, rimuovere il delegato e sostituirne l'utilizzo con il delegato System.EventHandler<TEventArgs>. Se il delegato viene generato automaticamente dal compilatore Visual Basic, modificare la sintassi della dichiarazione di evento per utilizzare il delegato System.EventHandler<TEventArgs>.

Esclusione di avvisi

Non escludere un avviso da questa regola.

Esempio

Nell'esempio riportato di seguito viene illustrato un delegato che viola la regola. Nell'esempio Visual Basic i commenti descrivono la procedura per modificare l'esempio in modo che soddisfi la regola. Per l'esempio nel linguaggio C#, di seguito è riportato un esempio che illustra il codice modificato.

Imports System

Namespace DesignLibrary

   Public Class CustomEventArgs
      Inherits EventArgs

      Public info As String = "data"

   End Class

   Public Class ClassThatRaisesEvent

      ' This statement creates a new delegate, which violates the rule.
      Event SomeEvent(sender As Object, e As CustomEventArgs)

      ' To satisfy the rule, comment out the previous line 
      ' and uncomment the following line.
      'Event SomeEvent As EventHandler(Of CustomEventArgs)

      Protected Overridable Sub OnSomeEvent(e As CustomEventArgs)
            RaiseEvent SomeEvent(Me, e)
      End Sub

      Sub SimulateEvent()
         OnSomeEvent(New CustomEventArgs())
      End Sub

   End Class

   Public Class ClassThatHandlesEvent

      Sub New(eventRaiser As ClassThatRaisesEvent)
         AddHandler eventRaiser.SomeEvent, AddressOf HandleEvent
      End Sub

      Private Sub HandleEvent(sender As Object, e As CustomEventArgs)
         Console.WriteLine("Event handled: {0}", e.info)
      End Sub

   End Class

   Class Test

      Shared Sub Main()

         Dim eventRaiser As New ClassThatRaisesEvent()
         Dim eventHandler As New ClassThatHandlesEvent(eventRaiser)

         eventRaiser.SimulateEvent()

      End Sub

   End Class

End Namespace
using System;

namespace DesignLibrary
{
   // This delegate violates the rule.
   public delegate void CustomEventHandler(
      object sender, CustomEventArgs e);

   public class CustomEventArgs : EventArgs
   {
      public string info = "data";
   }

   public class ClassThatRaisesEvent
   {
      public event CustomEventHandler SomeEvent;

      protected virtual void OnSomeEvent(CustomEventArgs e)
      {
         if(SomeEvent != null)
         {
            SomeEvent(this, e);
         }
      }

      public void SimulateEvent()
      {
         OnSomeEvent(new CustomEventArgs());
      }
   }

   public class ClassThatHandlesEvent
   {
      public ClassThatHandlesEvent(ClassThatRaisesEvent eventRaiser)
      {
         eventRaiser.SomeEvent += 
            new CustomEventHandler(HandleEvent);
      }

      private void HandleEvent(object sender, CustomEventArgs e)
      {
         Console.WriteLine("Event handled: {0}", e.info);
      }
   }

   class Test
   {
      static void Main()
      {
         ClassThatRaisesEvent eventRaiser = new ClassThatRaisesEvent();
         ClassThatHandlesEvent eventHandler = 
            new ClassThatHandlesEvent(eventRaiser);

         eventRaiser.SimulateEvent();
      }
   }
}

Nell'esempio seguente viene rimossa la dichiarazione del delegato dall'esempio precedente, che soddisfa la regola, e ne viene sostituito l'utilizzo nei metodi ClassThatRaisesEvent e ClassThatHandlesEvent con il delegato System.EventHandler<TEventArgs>.

using System;

namespace DesignLibrary
{
   public class CustomEventArgs : EventArgs
   {
      public string info = "data";
   }

   public class ClassThatRaisesEvent
   {
      public event EventHandler<CustomEventArgs> SomeEvent;

      protected virtual void OnSomeEvent(CustomEventArgs e)
      {
         if(SomeEvent != null)
         {
            SomeEvent(this, e);
         }
      }

      public void SimulateEvent()
      {
         OnSomeEvent(new CustomEventArgs());
      }
   }

   public class ClassThatHandlesEvent
   {
      public ClassThatHandlesEvent(ClassThatRaisesEvent eventRaiser)
      {
         eventRaiser.SomeEvent += 
            new EventHandler<CustomEventArgs>(HandleEvent);
      }

      private void HandleEvent(object sender, CustomEventArgs e)
      {
         Console.WriteLine("Event handled: {0}", e.info);
      }
   }

   class Test
   {
      static void Main()
      {
         ClassThatRaisesEvent eventRaiser = new ClassThatRaisesEvent();
         ClassThatHandlesEvent eventHandler = 
            new ClassThatHandlesEvent(eventRaiser);

         eventRaiser.SimulateEvent();
      }
   }
}

Regole correlate

CA1005: Evitare un uso eccessivo di parametri nei tipi generici

CA1010: Gli insiemi devono implementare un'interfaccia generica

CA1000: Non dichiarare membri statici su tipi generici

CA1002: Non esporre elenchi generici

CA1006: Non annidare tipi generici nelle firme dei membri

CA1004: I metodi generici devono fornire parametri di tipo

CA1007: Utilizzare generics dove appropriato

Vedere anche

Riferimenti

Generics (Guida per programmatori C#)