更新 : 2007 年 11 月
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();
}
}
}
関連規則
コレクションは、ジェネリック インターフェイスを実装しなければなりません
ジェネリック メソッドは型パラメータを指定しなければなりません