CA1003: Usar instâncias genéricas do manipulador de eventos
Propriedade | valor |
---|---|
ID da regra | CA1003 |
Cargo | Usar instâncias genéricas do manipulador de eventos |
Categoria | Desenho |
A correção está quebrando ou não quebrando | Quebrando |
Habilitado por padrão no .NET 8 | Não |
Causa
Um tipo contém um delegado que retorna void e cuja assinatura contém dois parâmetros (o primeiro um objeto e o segundo um tipo que é atribuível a EventArgs) e o assembly contendo destinos .NET.
Por padrão, essa regra examina apenas tipos visíveis externamente, mas isso é configurável.
Descrição da regra
Antes do .NET Framework 2.0, para passar informações personalizadas para o manipulador de eventos, um novo delegado tinha que ser declarado que especificava uma classe derivada da System.EventArgs classe. No .NET Framework 2.0 e versões posteriores, o delegado genérico System.EventHandler<TEventArgs> permite que qualquer classe derivada seja usada junto com o manipulador de EventArgs eventos.
Como corrigir violações
Para corrigir uma violação dessa regra, remova o delegado e substitua seu uso usando o System.EventHandler<TEventArgs> delegado.
Se o delegado for gerado automaticamente pelo compilador do Visual Basic, altere a sintaxe da declaração de evento para usar o System.EventHandler<TEventArgs> delegado.
Quando suprimir avisos
Não suprima um aviso desta regra.
Configurar código para análise
Use a opção a seguir para configurar em quais partes da base de código executar essa regra.
Você pode configurar essa opção apenas para esta regra, para todas as regras às quais ela se aplica ou para todas as regras nesta categoria (Design) às quais ela se aplica. Para obter mais informações, consulte Opções de configuração da regra de qualidade de código.
Incluir superfícies de API específicas
Você pode configurar em quais partes da sua base de código executar essa regra, com base em sua acessibilidade. Por exemplo, para especificar que a regra deve ser executada somente na superfície de API não pública, adicione o seguinte par chave-valor a um arquivo .editorconfig em seu projeto:
dotnet_code_quality.CAXXXX.api_surface = private, internal
Exemplo
O exemplo a seguir mostra um delegado que viola a regra. No exemplo do Visual Basic, os comentários descrevem como modificar o exemplo para satisfazer a regra. Para o exemplo C#, segue-se um exemplo que mostra 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 trecho de código a seguir remove a declaração de delegado do exemplo anterior, que satisfaz a regra. Ele substitui seu uso nos ClassThatRaisesEvent
métodos e ClassThatHandlesEvent
usando o System.EventHandler<TEventArgs> delegado.
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 conexas
- CA1005: Evite parâmetros excessivos em tipos genéricos
- CA1010: Coleções devem implementar interface genérica
- CA1000: Não declarar membros estáticos em tipos genéricos
- CA1002: Não exponha listas genéricas