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