Uwaga
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Własność | Wartość |
---|---|
Identyfikator reguły | CA1003 |
Tytuł | Użyj ogólnych instancji obsługi zdarzeń |
Kategoria | Design |
Poprawka rozbijająca lub nierozbijająca | Kluczowa |
Domyślnie włączone na platformie .NET 9 | Nie. |
Przyczyna
Typ zawiera delegata, który zwraca void, a jego sygnatura zawiera dwa parametry (pierwszym jest obiekt, a drugi to typ, który można przypisać do EventArgs), a zestaw, który go zawiera, jest przeznaczony dla platformy .NET.
Domyślnie ta reguła analizuje tylko typy widoczne zewnętrznie, ale można to skonfigurować.
Opis reguły
Przed .NET Framework 2.0, aby przekazać informacje niestandardowe do procedury obsługi zdarzeń, należało zadeklarować nowy delegat, który specyfikował klasę pochodzącą z klasy System.EventArgs. W .NET Framework 2.0 i nowszych wersjach delegat ogólny System.EventHandler<TEventArgs> umożliwia używanie dowolnej klasy pochodzącej z EventArgs wraz z programem 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ć, na które części bazy kodu będzie miała wpływ ta reguła.
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óre części bazy kodu ma wpływać ta reguła, na podstawie ich poziomu dostępu, ustawiając opcję api_surface. 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
Notatka
Zastąp część XXXX
CAXXXX
identyfikatorem odpowiedniej reguły.
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: {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: {e.info}");
}
}
class Test
{
static void MainEvent()
{
var eventRaiser = new ClassThatRaisesEvent();
var eventHandler = new ClassThatHandlesEvent(eventRaiser);
eventRaiser.SimulateEvent();
}
}
Powiązane reguły
- CA1005: Unikaj nadużywania parametrów w typach ogólnych
- CA1010: Kolekcje powinny implementować interfejs ogólny
- CA1000: Nie deklaruj składowych statycznych w typach ogólnych
- CA1002: Nie ujawniaj list ogólnych