다음을 통해 공유


CA1003: 제네릭 이벤트 처리기 인스턴스를 사용하십시오.

속성
규칙 ID 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 표면에서만 실행되도록 지정하려면 프로젝트의 .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 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();
    }
}

다음 코드 조각에서는 규칙을 충족하는 이전 예제에서 대리자 선언을 제거합니다. System.EventHandler<TEventArgs> 대리자를 사용하여 ClassThatRaisesEvent 메서드 및 ClassThatHandlesEvent 메서드에서의 사용을 대체합니다.

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

참고 항목