CA1003: используйте экземпляры обработчика универсальных событий
Свойство | Значение |
---|---|
Идентификатор правила | CA1003 |
Заголовок | Используйте экземпляры обработчика универсальных событий |
Категория | Проектирование |
Исправление является критическим или не критическим | Критическое |
Включен по умолчанию в .NET 9 | No |
Причина
Тип содержит делегат, возвращающий значение void, сигнатура которого содержит два параметра (первый — объект, а второй — тип, который может быть назначен EventArgs), а включающая сборка предназначена для платформы .NET.
По умолчанию это правило проверяет только видимые извне типы, но это поведение можно настроить.
Описание правила
До выхода .NET Framework 2.0 для передачи пользовательских сведений в обработчик событий необходимо было объявить новый делегат, который указывал класс, производный от класса System.EventArgs. Начиная с .NET Framework 2.0 универсальный делегат System.EventHandler<TEventArgs> позволяет использовать вместе с обработчиком событий любой класс, производный от EventArgs.
Устранение нарушений
Чтобы устранить нарушение этого правила, удалите делегат и используйте вместо него делегат System.EventHandler<TEventArgs>.
Если делегат создается автоматически компилятором Visual Basic, измените синтаксис объявления события, чтобы он использовал делегат System.EventHandler<TEventArgs>.
Когда лучше отключить предупреждения
Для этого правила отключать вывод предупреждений не следует.
Настройка кода для анализа
Используйте следующий параметр, чтобы выбрать части базы кода для применения этого правила.
Этот параметр можно настроить только для этого правила, для всех правил, к которым он применяется, или для всех правил в этой категории (конструкторе), к которым она применяется. Дополнительные сведения см. в статье Параметры конфигурации правила качества кода.
Включение определенных контактных зон API
Вы можете настроить, для каких частей базы кода следует выполнять это правило в зависимости от их доступности. Например, чтобы указать, что правило должно выполняться только для закрытой контактной зоны API, добавьте следующую пару "ключ-значение" в файл EDITORCONFIG в своем проекте:
dotnet_code_quality.CAXXXX.api_surface = private, internal
Пример
В следующем примере показан делегат, нарушающий это правило: В примере на Visual Basic в комментариях описано, как изменить этот пример для соответствия правилу. В примере на C# дальше показан пример измененного кода.
Imports System
Namespace ca1003
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 Main1003()
Dim eventRaiser As New ClassThatRaisesEvent()
Dim eventHandler As New ClassThatHandlesEvent(eventRaiser)
eventRaiser.SimulateEvent()
End Sub
End Class
End Namespace
// 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)
{
SomeEvent?.Invoke(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 MainEvent()
{
var eventRaiser = new ClassThatRaisesEvent();
var eventHandler = new ClassThatHandlesEvent(eventRaiser);
eventRaiser.SimulateEvent();
}
}
В следующем фрагменте кода удаляется объявление делегата из предыдущего примера для соответствия правилу. Этот делегат, используемый в методах ClassThatRaisesEvent
и ClassThatHandlesEvent
, заменяется на делегат System.EventHandler<TEventArgs>.
public class CustomEventArgs : EventArgs
{
public string info = "data";
}
public class ClassThatRaisesEvent
{
public event EventHandler<CustomEventArgs>? SomeEvent;
protected virtual void OnSomeEvent(CustomEventArgs e)
{
SomeEvent?.Invoke(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 MainEvent()
{
var eventRaiser = new ClassThatRaisesEvent();
var eventHandler = new ClassThatHandlesEvent(eventRaiser);
eventRaiser.SimulateEvent();
}
}
Связанные правила
- CA1005: не используйте слишком много параметров в универсальных типах
- CA1010: коллекции должны реализовывать универсальный интерфейс
- CA1000: не объявляйте статические элементы в универсальных типах
- CA1002: не следует раскрывать универсальные списки