共用方式為


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

屬性
規則識別碼 CA1003
職稱 使用泛型事件處理器實例
類別 設計
此修正為破壞性或非破壞性 中斷
預設在 .NET 9 中啟用

原因

類型中包含一個傳回 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_surface] 選項,根據程式代碼基底的存取範圍,設定執行此規則的哪些部分。 例如,若要指定規則只應該針對非公用 API 介面執行,請將下列機碼/值組新增至 專案中的 .editorconfig 檔案:

dotnet_code_quality.CAXXXX.api_surface = private, internal

注意

以適用規則的標識碼取代 XXXXCAXXXX 部分。

範例

下列範例顯示委派違反了規則。 在 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 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();
    }
}

下列代碼段會從符合規則的上一個範例中移除委派宣告。 它以 System.EventHandler<TEventArgs> 委派取代其在 ClassThatRaisesEventClassThatHandlesEvent 方法中的用法。

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

另請參閱