CA1003:使用一般事件處理常式執行個體

屬性
規則識別碼 CA1003
標題 使用一般事件處理常式執行個體
類別 設計
修正程式是中斷或非中斷 中斷
預設在 .NET 8 中啟用 No

原因

類型包含傳回 void 的委派,其簽章包含兩個參數(第一個是物件,第二個是可指派給 EventArgs 的類型),以及包含的元件目標為 .NET。

根據預設,此規則只會查看外部可見的類型,但這是可設定

檔案描述

在 .NET Framework 2.0 之前,若要將自定義資訊傳遞至事件處理程式,必須宣告新的委派,以指定衍生自 類別的 System.EventArgs 類別。 在 .NET Framework 2.0 和更新版本中,泛型 System.EventHandler<TEventArgs> 委派允許衍生自 EventArgs 的任何類別與事件處理程式一起使用。

如何修正違規

若要修正此規則的違規,請移除委派,並使用委派來取代其使用 System.EventHandler<TEventArgs> 方式。

如果 Visual Basic 編譯程式自動產生委派,請將事件宣告的語法變更為使用 System.EventHandler<TEventArgs> 委派。

隱藏警告的時機

請勿隱藏此規則的警告。

設定程式代碼以分析

使用下列選項來設定程式代碼基底要執行此規則的部分。

您可以只針對此規則、針對它套用的所有規則,或針對套用至此類別的所有規則,或針對它套用的所有規則,設定此選項。 如需詳細資訊,請參閱 程式代碼品質規則組態選項

包含特定 API 介面

您可以根據程式代碼基底的存取範圍,設定要執行此規則的部分。 例如,若要指定規則只應該針對非公用 API 介面執行,請將下列機碼/值組新增至 專案中的 .editorconfig 檔案:

dotnet_code_quality.CAXXXX.api_surface = private, internal

範例

下列範例顯示違反規則的委派。 在 Visual Basic 範例中,批註描述如何修改範例以滿足規則。 針對 C# 範例,下列範例會顯示修改過的程式代碼。

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 Main()

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

下列代碼段會從符合規則的上一個範例中移除委派宣告。 它會使用 委派來取代其在 和 ClassThatHandlesEvent 方法中的ClassThatRaisesEvent用法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();
    }
}

另請參閱