Udostępnij za pośrednictwem


CA1003: Użyj wystąpień obsługi zdarzeń generycznych

Właściwości Wartość
Identyfikator reguły CA1003
Tytuł Użyj ogólnych wystąpień procedury obsługi zdarzeń
Kategoria Projekt
Poprawka powodująca niezgodność lub niezgodność Kluczowa
Domyślnie włączone na platformie .NET 9 Nie.

Przyczyna

Typ zawiera delegata, który zwraca wartość void i którego podpis zawiera dwa parametry (pierwszy obiekt i drugi typ, który można przypisać do usługi EventArgs) oraz zawierający zestaw docelowy platformy .NET.

Domyślnie ta reguła analizuje tylko typy widoczne zewnętrznie, ale można to skonfigurować.

Opis reguły

Przed programem .NET Framework 2.0, aby przekazać informacje niestandardowe do procedury obsługi zdarzeń, należy zadeklarować nowy delegat, który określił klasę, która pochodzi z System.EventArgs klasy. W programie .NET Framework 2.0 i nowszych wersjach delegat ogólny System.EventHandler<TEventArgs> umożliwia używanie dowolnej klasy pochodzącej z EventArgs programu obsługi zdarzeń.

Jak naprawić naruszenia

Aby naprawić naruszenie tej reguły, usuń delegata i zastąp jego użycie przy użyciu delegata System.EventHandler<TEventArgs> .

Jeśli delegat jest generowany automatycznie przez kompilator języka Visual Basic, zmień składnię deklaracji zdarzenia, aby użyć delegata System.EventHandler<TEventArgs> .

Kiedy pomijać ostrzeżenia

Nie pomijaj ostrzeżeń dla tej reguły.

Konfigurowanie kodu do analizowania

Użyj następującej opcji, aby skonfigurować, które części bazy kodu mają być uruchamiane w tej regule.

Tę opcję można skonfigurować tylko dla tej reguły, dla wszystkich reguł, do których ma ona zastosowanie, lub dla wszystkich reguł w tej kategorii (Projekt), których dotyczy. Aby uzyskać więcej informacji, zobacz Opcje konfiguracji reguły jakości kodu.

Uwzględnij określone powierzchnie interfejsu API

Możesz skonfigurować, na których częściach bazy kodu ma być uruchamiana ta reguła, na podstawie ich ułatwień dostępu. Aby na przykład określić, że reguła powinna być uruchamiana tylko na powierzchni niepublicznego interfejsu API, dodaj następującą parę klucz-wartość do pliku editorconfig w projekcie:

dotnet_code_quality.CAXXXX.api_surface = private, internal

Przykład

W poniższym przykładzie pokazano delegata, który narusza regułę. W przykładzie języka Visual Basic komentarze opisują sposób modyfikowania przykładu w celu spełnienia reguły. W przykładzie w języku C# pokazano zmodyfikowany kod.

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();
    }
}

Poniższy fragment kodu usuwa deklarację delegata z poprzedniego przykładu, która spełnia regułę. Zastępuje jego użycie w metodach ClassThatRaisesEvent i ClassThatHandlesEvent przy użyciu delegata 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();
    }
}

Zobacz też