CA1003: 汎用イベント ハンドラーのインスタンスを使用します
TypeName |
UseGenericEventHandlerInstances |
CheckId |
CA1003 |
[カテゴリ] |
Microsoft.Design |
互換性に影響する変更点 |
あり |
原因
型に void を返すデリゲートが含まれており、デリゲートのシグネチャに 2 つのパラメーター (1 つはオブジェクト、もう 1 つは EventArgs に割り当て可能な型) が含まれ、包含アセンブリの対象が .NET Framework 2.0 です。
規則の説明
.NET Framework 2.0 より前のバージョンでは、イベント ハンドラーにカスタム情報を渡すために、System.EventArgs クラスから派生したクラスを指定する、新しいデリゲートを宣言する必要がありました。System.EventHandler<TEventArgs> デリゲートを導入した .NET Framework 2.0 では、これは不要になりました。この汎用デリゲートを使用することで、EventArgs から派生した任意のクラスをイベント ハンドラーと共に使用することができます。
違反の修正方法
この規則違反を修正するには、デリゲートを削除し、代わりに System.EventHandler<TEventArgs> デリゲートを使用します。デリゲートが Visual Basic コンパイラによって自動生成されている場合、System.EventHandler<TEventArgs> デリゲートを使用するようにイベント宣言の構文を変更してください。
警告を抑制する状況
この規則による警告は抑制しないでください。
使用例
この規則に違反するデリゲートを次の例に示します。Visual Basic の例では、規則を満たすように例を変更する方法をコメントで説明しています。C# の例では、修正されたコードを表示しています。
Imports System
Namespace DesignLibrary
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
using System;
namespace DesignLibrary
{
// 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)
{
if(SomeEvent != null)
{
SomeEvent(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 Main()
{
ClassThatRaisesEvent eventRaiser = new ClassThatRaisesEvent();
ClassThatHandlesEvent eventHandler =
new ClassThatHandlesEvent(eventRaiser);
eventRaiser.SimulateEvent();
}
}
}
次に示す例では、前述の規則を満たしている例からデリゲート宣言を削除し、その代わりに ClassThatRaisesEvent メソッドおよび ClassThatHandlesEvent メソッドで System.EventHandler<TEventArgs> デリゲートを使用しています。
using System;
namespace DesignLibrary
{
public class CustomEventArgs : EventArgs
{
public string info = "data";
}
public class ClassThatRaisesEvent
{
public event EventHandler<CustomEventArgs> SomeEvent;
protected virtual void OnSomeEvent(CustomEventArgs e)
{
if(SomeEvent != null)
{
SomeEvent(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 Main()
{
ClassThatRaisesEvent eventRaiser = new ClassThatRaisesEvent();
ClassThatHandlesEvent eventHandler =
new ClassThatHandlesEvent(eventRaiser);
eventRaiser.SimulateEvent();
}
}
}
関連規則
CA1005: ジェネリック型でパラメーターを使用しすぎないでください
CA1010: コレクションは、ジェネリック インターフェイスを実装しなければなりません
CA1006: ジェネリック型をメンバー シグネチャ内で入れ子にしません
CA1004: ジェネリック メソッドは型パラメーターを指定しなければなりません