Export (0) Print
Expand All
Expand Minimize

Use generic event handler instances

TypeName

UseGenericEventHandlerInstances

CheckId

CA1003

Category

Microsoft.Design

Breaking Change

Breaking

A type contains a delegate that returns void, whose signature contains two parameters (the first an object and the second a type that is assignable to EventArgs), and the containing assembly targets .NET Framework 2.0.

Before .NET Framework 2.0, in order to pass custom information to the event handler, a new delegate had to be declared that specified a class derived from the System.EventArgs class. This is no longer true in .NET Framework 2.0, which introduced the System.EventHandler delegate. This generic delegate allows any class derived from EventArgs to be used with the event handler.

To fix a violation of this rule, remove the delegate and replace its use with the System.EventHandler delegate. If the delegate is auto-generated by the Visual Basic compiler, change the syntax of the event declaration to use the System.EventHandler delegate.

Do not exclude a warning from this rule.

The following example shows a delegate that violates the rule. In the Visual Basic example, comments describe how to modify the example to satisfy the rule. For the C# example, an example follows that shows the modified code.

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

The following example removes the delegate declaration from the previous example, which satisfies the rule, and replaces its use in the ClassThatRaisesEvent and ClassThatHandlesEvent methods with the System.EventHandler delegate.

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

Community Additions

ADD
Show:
© 2014 Microsoft