CA1003:使用泛型事件处理程序实例

类型名

UseGenericEventHandlerInstances

CheckId

CA1003

类别

Microsoft.Design

是否重大更改

原因

类型包含返回 void 的委托,该委托的签名包含两个参数(第一个参数是对象,第二个参数是可以分配给 EventArgs 的类型),而且包含程序集针对的是 .NET Framework 2.0。

规则说明

在 .NET Framework 2.0 之前,为了将自定义信息传递给事件处理程序,必须声明新的委托以指定从 System.EventArgs 类派生的类。 在 .NET Framework 2.0 中,由于引入了 System.EventHandler<TEventArgs> 委托,则不必如此。 该泛型委托允许从 EventArgs 派生的任何类与事件处理程序一起使用。

如何解决冲突

若要修复与该规则的冲突,请移除该委托,而代之以 System.EventHandler<TEventArgs> 委托。 如果该委托是由 Visual Basic 编译器自动生成的,则应更改事件声明的语法以使用 System.EventHandler<TEventArgs> 委托。

何时禁止显示警告

不要禁止显示此规则发出的警告。

示例

下面的示例演示一个与该规则冲突的委托。 在 Visual Basic 示例中,注释描述了如何修改示例以满足该规则。 对于 C# 示例,后面的示例显示了修改后的代码。

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

为了满足该规则,下面的示例从上面的示例中移除委托声明,并将 ClassThatRaisesEvent 和 ClassThatHandlesEvent 方法中出现的该委托的匹配项替换为 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();
      }
   }
}

相关规则

CA1005:避免泛型类型的参数过多

CA1010:集合应实现泛型接口

CA1000:不要在泛型类型中声明静态成员

CA1002:不要公开泛型列表

CA1006:不要将泛型类型嵌套在成员签名中

CA1004:泛型方法应提供类型参数

CA1007:在适用处使用泛型

请参见

参考

泛型(C# 编程指南)