Partilhar via


CA1003: Usar instâncias genéricas do manipulador de eventos

Property valor
ID da regra CA1003
Título 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 9 Não

Motivo

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 que era 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 sua 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 delegate 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();
    }
}

Consulte também