0

我有一个 MyCol 类,它继承自 ObservableCollection(Of T)。它以这种方式覆盖 InsertItem 方法:

Public Event PreInsertItem As EventHandler(Of EventArgs)

Protected Overridable Sub OnPreInsertItem(e As EventAtgs)
    RaiseEvent PreInsertItem(Me, e)
End Sub

Protected Overrides Sub InsertItem(index As Integer, item As T)
    OnPreInsertItem(EventArgs.Empty)

    MyBase.InsertItem(index, item)
End Sub

如您所见,我添加了一个事件,每次将项目添加到 MyCol 集合时都会引发该事件。

接下来我创建另一个类 MyColSubClass,它继承自 MyCol,并且还覆盖了 InsertItem 方法:

Public Overrides Sub InsertItem(index as Integer, item as T)
    OnPreInsertItem(EventArgs.Empty)

    ' some additional code goes here

    MyBase.InsertItem(index, item)
End Sub

问题:

现在,当我使用 MyColSubClass 的一个实例并添加一个项目时,PreInsertItem事件会引发两次:首先是在 MyColSubClass 中,然后是在 MyCol 中。

我应该使用什么设计模式来使 PreInsertItem 事件只引发一次:在 MyColSubClass 中?

注意

示例中显示的类和事件是从现实生活中的应用程序简化而来的,但假设它们显示了应用程序的确切结构。在最后一个继承的类中引发事件是必须的。

4

3 回答 3

1

如果您确定基类会引发事件,那么在派生类中这样做是没有用的。

只需将您的覆盖更改为:

Public Overrides Sub InsertItem(index as Integer, item as T)
    ' some additional code goes here

    MyBase.InsertItem(index, item)
End Sub

那应该没问题。

但是,如果您更改派生方法并停止调用 MyBase.InsertItem(...),您应该在覆盖中引发事件以确保它被引发:

Public Overrides Sub InsertItem(index as Integer, item as T)
    ' some additional code goes here

    OnPreInsertItem(EventArgs.Empty)

    ' insert your item and do whatever...
End Sub

编辑

如果您需要更改引发事件的方式,但想确保它只引发一次,只需覆盖派生类中的 OnPreInsertItem 方法:

Protected Overrides Sub OnPreInsertItem(e as EventArgs)
    ' Do wahetever you need here, change e, add info, whatever...
    ' ...
    ' Then raise the event (or call MyBase.OnPreInsertItem, as you like)
    RaiseEvent PreInsertItem(Me, e)
End Sub

Public Overrides Sub InsertItem(index as Integer, item as T)
    ' some additional code goes here

    ' This will work only if MyBase.InsertItem calls OnPreInsertItem. 
    ' Otherwise, you have to handle the insertion and raise the event
    ' yourself without calling the base method.
    MyBase.InsertItem(index, item)
End Sub

由于 OnPreInsertItem 是可重写的,因此当您在派生类中插入项目时,将调用派生类的版本。

希望有帮助:)

于 2012-07-11T12:05:30.073 回答
0

我认为你不应该OnPreInsertItem在你的子类 MyColSubClass 中提出。
你的方法应该是这样的:

Public Overrides Sub InsertItem(index as Integer, item as T)
    ' some additional code goes here

    MyBase.InsertItem(index, item)
End Sub

您正在扩展基类的某些功能。如果您要替换该特定功能,那么您的方法应该是这样的:

Public Overrides Sub InsertItem(index as Integer, item as T)
    OnPreInsertItem(EventArgs.Empty)

    ' some additional code goes here

End Sub

您可以在此处此处找到更多信息。

于 2012-07-11T12:09:46.503 回答
0

如果我做对了,您想在不同的继承级别上向 EventArg 类添加信息。在这种情况下,在我看来,提供与引发事件相同级别的 EventArg 成员是最好的解决方案,而 InsertItem() 的所有覆盖只是修改此 EventArg 成员,事件以及此 eventargs 仅在尽可能高的情况下引发等级。

于 2012-07-11T12:40:18.380 回答