Partager via


Utiliser des instances du gestionnaire d'événements génériques

Mise à jour : novembre 2007

TypeName

UseGenericEventHandlerInstances

CheckId

CA1003

Catégorie

Microsoft.CSharp

Modification avec rupture

Oui

Cause

Un type contient un délégué qui retourne void, dont la signature contient deux paramètres (le premier est un objet et le second est un type pouvant être assigné à EventArgs), et l'assembly conteneur cible le .NET Framework 2.0.

Description de la règle

Dans les versions antérieures du .NET Framework 2.0, un nouveau délégué qui spécifiait une classe dérivée de la classe System.EventArgs devait être déclaré pour passer des informations personnalisées au gestionnaire d'événements. Ce n'est plus le cas dans le .NET Framework 2.0, qui a introduit le délégué System.EventHandler<TEventArgs>. Ce délégué générique permet d'utiliser une classe dérivée de EventArgs avec le gestionnaire d'événements.

Comment corriger les violations

Pour corriger une violation de cette règle, supprimez le délégué et remplacez son utilisation par le délégué System.EventHandler<TEventArgs>. Si le délégué est généré automatiquement par le compilateur Visual Basic, modifiez la syntaxe de la déclaration de l'événement pour utiliser le délégué System.EventHandler<TEventArgs>.

Quand supprimer les avertissements

Ne supprimez aucun avertissement de cette règle.

Exemple

L'exemple suivant présente un délégué qui ne respecte pas la règle. Dans l'exemple Visual Basic, les commentaires expliquent comment modifier l'exemple pour satisfaire à la règle. Pour l'exemple C#, l'exemple qui suit présente le code modifié.

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();
      }
   }
}

L'exemple suivant supprime la déclaration de délégué de l'exemple précédent, qui respecte la règle, et remplace son utilisation dans les méthodes ClassThatRaisesEvent et ClassThatHandlesEvent par le délégué 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();
      }
   }
}

Règles connexes

Éviter les paramètres excessifs sur les types génériques

Les collections doivent implémenter l'interface générique

Ne pas déclarer de membres statiques sur les types génériques

Ne pas exposer de listes génériques

Ne pas imbriquer les types génériques dans les signatures de membre

Les méthodes génériques doivent fournir le paramètre de type

Utiliser des classes génériques lorsque nécessaire

Voir aussi

Référence

Génériques (Guide de programmation C#)