gpt4 book ai didi

.net - 使用委托(delegate)和声明事件

转载 作者:行者123 更新时间:2023-12-01 13:08:54 25 4
gpt4 key购买 nike

我正在开发一个供其他开发人员使用的类库,将允许他们使用 WithEvents(或其他语言中的类似方法)声明我的类的实例,并允许他们使用类中定义的委托(delegate).我这样做只是多余吗?

Public Delegate Sub TimerElapsedDelegate(ByVal sender As Object, ByVal e As System.EventArgs)
Public Event TimerElapsed(ByVal sender As Object, ByVal e As System.EventArgs)
Private _TimerElapsed As TimerElapsedDelegate = Nothing

或者我应该只声明事件并让它们执行 AddHandler 等操作吗?

感谢您对此的任何建议......我认为我是多余的并且不想要无意义的代码,更不用说避免 DRY 原则了。

{edit}只是想发布剩余的代码,并强调此类实例执行的“工作”是在单独的线程上完成的。{/edit}

#Region "Delegates"
Public Delegate Sub TimerElapsedDelegate(ByVal sender As Object, ByVal e As System.EventArgs)
Public Event TimerElapsed(ByVal sender As Object, ByVal e As System.EventArgs)
Private _TimerElapsed As TimerElapsedDelegate = Nothing
Public Property OnTimerElapsed() As TimerElapsedDelegate
Get
Return _TimerElapsed
End Get
Set(ByVal value As TimerElapsedDelegate)
If value Is Nothing Then
_TimerElapsed = Nothing
Else
If _TimerElapsed Is Nothing Then
_TimerElapsed = value
Else
_TimerElapsed = System.Delegate.Combine(_TimerElapsed, value)
End If
End If
End Set
End Property
Private Sub TriggerTimerElapsed()
If OnTimerElapsed IsNot Nothing Then
OnTimerElapsed.Invoke(Me, New System.EventArgs)
End If
RaiseEvent TimerElapsed(Me, New System.EventArgs)
End Sub

Public Delegate Sub ItemReadyForQueueDelegate(ByVal sender As Object, ByVal e As System.EventArgs)
Public Event ItemReadyForQueue(ByVal sender As Object, ByVal e As System.EventArgs)
Private _ItemReadyForQueue As ItemReadyForQueueDelegate = Nothing
Public Property OnItemReadyForQueue() As ItemReadyForQueueDelegate
Get
Return _ItemReadyForQueue
End Get
Set(ByVal value As ItemReadyForQueueDelegate)
If value Is Nothing Then
_ItemReadyForQueue = Nothing
Else
If _ItemReadyForQueue Is Nothing Then
_ItemReadyForQueue = value
Else
_ItemReadyForQueue = System.Delegate.Combine(_ItemReadyForQueue, value)
End If
End If
End Set
End Property
Private Sub TriggerItemReadyForQueue(ByVal oItem As h3Budgeteer.FileSystem.ReportTemplateFile.ReportTemplate)
If OnItemReadyForQueue IsNot Nothing Then
OnItemReadyForQueue.Invoke(Me, New ItemReadyForQueueEventArgs(oItem))
End If
RaiseEvent ItemReadyForQueue(Me, New ItemReadyForQueueEventArgs(oItem))
End Sub
Public Class ItemReadyForQueueEventArgs
Inherits System.EventArgs
Private _ReportTemplate As h3Budgeteer.FileSystem.ReportTemplateFile.ReportTemplate = Nothing
Public ReadOnly Property ReportTemplate() As h3Budgeteer.FileSystem.ReportTemplateFile.ReportTemplate
Get
Return _ReportTemplate
End Get
End Property
Public Sub New(ByVal oReportTemplate As h3Budgeteer.FileSystem.ReportTemplateFile.ReportTemplate)
_ReportTemplate = oReportTemplate
End Sub
End Class

结束区域

最佳答案

我会说完全完全删除您的委托(delegate)。

您的委托(delegate)正在做与事件完全相同的事情。您几乎是在编写自己的事件管道,而不是使用框架的事件调用。事件与您编写的内容几乎完全相同,只是它更易于使用,并且还可以更轻松地取消订阅该事件。

同时提供两者没有任何优势 - 该事件会执行您的“委托(delegate)”所做的一切,并且更加清晰。

(以前:)

If you're developing this as a class library, I would suggest just making your class not be sealed, and following the more standard approach. The normal approach for allowing logic to be overridden or inserted into your code and allowing events would be to provide hooks for subclassing.

Delegates could be used in a situation like this to allow the user to plug in their own logic. However, in many cases, having protected virtual functions makes this more clear, and much easier to accomplish.

Events should be exactly that, an event that notifies the user of some "event". These should be hooks where the user attaches their delegate.

For example, instead of providing delegates and events, the base Windows Forms controls use a protected method (ie: OnMouseDown) and an event that's triggered by default (MouseDown).

This allows a user to subclass your class and override the logic (which is probably why you'd want delegates) as well as handle the event.

The one place where I would provide delegates is in rare cases where your class or method REQUIRES logic to be added by a user. In this case, you can either provide an abstract base class, or have a delegate that is passed in for that logic. A good example of this is the .Where() method in LINQ. Where is useless without the predicate used for filtering, so passing in a delegate makes sense in this case. Note, though, that there is no event associated with this - it's really there to provide a different function.

关于.net - 使用委托(delegate)和声明事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/667050/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com