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
注意
以適用規則的標識碼取代 XXXX
的 CAXXXX
部分。
範例
下列範例顯示委派違反了規則。 在 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> 委派取代其在 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: {e.info}");
}
}
class Test
{
static void MainEvent()
{
var eventRaiser = new ClassThatRaisesEvent();
var eventHandler = new ClassThatHandlesEvent(eventRaiser);
eventRaiser.SimulateEvent();
}
}