Используйте экземпляры обработчика универсальных событий
Обновлен: Ноябрь 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#)