通过


CA1003:使用泛型事件处理程序实例

属性
规则 ID CA1003
标题 使用泛型事件处理程序实例
类别 设计
修复会引起中断还是不会引起中断 突发
在 .NET 10 中默认启用
适用的语言 C# 和 Visual Basic

原因

某个类型包含一个返回 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 部分替换为适用规则的 ID。

示例

下面的示例展示了违反此规则的委托。 在 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();
    }
}

另请参阅