CA1003: Usar instâncias do manipulador de eventos genérico
Property | Valor |
---|---|
ID da regra | CA1003 |
Título | Usar instâncias do manipulador de eventos genérico |
Categoria | Projetar |
Correção interruptiva ou sem interrupção | Quebra |
Habilitado por padrão no .NET 9 | Não |
Causa
Um tipo contém um representante que retorna nulo, cuja assinatura contém dois parâmetros (o primeiro é um objeto e o segundo é um tipo atribuível a EventArgs), e o destino do assembly de contenção é o .NET.
Por padrão, essa regra analisa apenas os tipos visíveis externamente, mas isso é configurável.
Descrição da regra
Antes do .NET Framework 2.0, para transmitir informações personalizadas ao manipulador de eventos, um novo representante tinha de ser declarado para especificar uma classe derivada da classe System.EventArgs. No .NET Framework 2.0 e versões posteriores, o representante genérico System.EventHandler<TEventArgs> permite que qualquer classe derivada de EventArgs seja usada com o manipulador de eventos.
Como corrigir violações
Para corrigir uma violação dessa regra, remova o representante e substitua seu uso pelo uso do representante System.EventHandler<TEventArgs>.
Se o representante for gerado automaticamente pelo compilador do Visual Basic, altere a sintaxe da declaração de evento para usar o representante System.EventHandler<TEventArgs>.
Quando suprimir avisos
Não suprima um aviso nessa regra.
Configurar código para analisar
Use a opção a seguir para configurar em quais partes da base de código essa regra deve ser executada.
Você pode configurar essa opção apenas para essa regra, para todas as regras às quais ela se aplica ou para todas as regras nessa categoria (Design) às quais ela se aplica. Para saber mais, confira Opções de configuração de regra de qualidade de código.
Incluir superfícies de API específicas
É possível configurar em quais partes da base de código essa regra deverá ser executada, com base na acessibilidade. Por exemplo, para especificar que a regra deverá ser executada apenas na superfície de API não pública, adicione o seguinte par chave-valor a um arquivo .editorconfig no projeto:
dotnet_code_quality.CAXXXX.api_surface = private, internal
Exemplo
O exemplo a seguir mostra um representante que viola a regra. No exemplo do Visual Basic, os comentários descrevem como modificar o exemplo para atender à regra. No caso do exemplo em C#, veja a seguir um exemplo com o código modificado.
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();
}
}
O snippet de código a seguir remove a declaração de representante do exemplo anterior, que atende à regra. Ele substitui seu uso nos métodos e ClassThatRaisesEvent
ClassThatHandlesEvent
pelo uso do representante 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();
}
}
Regras relacionadas
- CA1005: Evitar parâmetros excessivos em tipos genéricos
- CA1010: Coleções devem implementar uma interface genérica
- CA1000: Não declarar membros estáticos em tipos genéricos
- CA1002: Não expor listas genéricas