Поделиться через


Используйте экземпляры обработчика универсальных событий

Обновлен: Ноябрь 2007

TypeName

UseGenericEventHandlerInstances

CheckId

CA1003

Категория

Microsoft.Design

Критическое изменение

Критическое

Причина

Тип содержит делегат, возвращающий пустое значение, подпись которого содержит два параметра (первый – объект, а второй – тип, которые могут быть назначены 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();
      }
   }
}

Связанные правила

Не используйте слишком много параметров в универсальных типах

Коллекции должны реализовать универсальный интерфейс

Не объявляйте статические элементы в универсальных типах

Не следует раскрывать универсальные списки

Не вкладывайте универсальные типы в подписи членов

Универсальные методы должны предоставлять параметр типа

Используйте универсальные методы, если это уместно

См. также

Ссылки

Универсальные шаблоны (Руководство по программированию на C#)