3

好的,所以我有一个声明 event 的基类StatusTextChanged。我的孩子班,当然不能直接提出这个事件。

所以我结束了这样的事情(为了简单起见):

Public MustInherit Class FooBase
    Public Event StatusTextChanged(ByVal StatusText As String)
    Protected Sub RaiseStatusTextChangedEvent(ByVal StatusText As String)
        RaiseEvent StatusTextChanged(StatusText)
    End Sub
End Class

然后在我调用的子类中 MyBase.RaiseStatusTextChangedEvent("something")。有没有更好或更推荐的方法来做到这一点?

编辑:VB.NET 或 C#,无论哪种方式,它的工作原理基本相同。

编辑:所以在响应之后,我在基类中,然后只需在子类中设置 StatusText 属性......

    Public Event StatusTextChanged(ByVal StatusText As String)
    Private _StatusText As String = "Idle."
    Public Property StatusText() As String
        Get
            Return _StatusText
        End Get
        Protected Set(ByVal value As String)
            RaiseEvent StatusTextChanged(value)
        End Set
    End Property
4

5 回答 5

6

我会说您非常接近推荐的方式(或者至少是我推荐的方式)。

如果可以选择,我会对您的代码进行一些更改:

  • 使 StatusTextChangedProtected Overridable
  • 在自定义 EventArgs 类中包装 StatusText
  • 将 StatusTextChanged 声明更改为Public Event StatusTextChanged As EventHandler(Of YourCustomEventArgs)

结果代码:

自定义 eventargs 类:

Public Class TextEventArgs
    Inherits EventArgs

    Private _text As String

    Public Sub New(ByVal text As String)
        _text = text
    End Sub

    Public ReadOnly Property Text() As String
        Get
            Return _text
        End Get
    End Property

End Class

基类中的事件实现:

Public Event StatusTextChanged As EventHandler(Of TextEventArgs)
Protected Overridable Sub OnStatusTextChanged(ByVal e As TextEventArgs)
    RaiseEvent StatusTextChanged(Me, e)
End Sub

...最后是引发事件的代码行;在基类或继承它的类中:

OnStatusTextChanged(New TextEventArgs("some text"))

这将更符合在 .NET 框架的其余部分中设计事件的方式。

于 2009-05-19T14:55:43.543 回答
1

除非您的子类特别需要覆盖基类方法,否则我会说调用基类实现绝对是最好的解决方案。

于 2009-05-19T14:47:55.057 回答
0

对于此类场景,这几乎是通过派生类在基类上引发事件的标准方法。

但是,这可能会有所改变,具体取决于谁控制了层次结构的 StatusText。如果 FooBase 中有一个只能通过访问器更改的具体 StatusText 支持字段,那么我不会让孩子控制 StatusTextChanged 事件的引发。相反,我会强制在 StatusText 属性的 Setter 中引发事件。这给了父类更多的控制权来执行它想要的关于何时和何时不引发所述事件的任何合同。

但是,如果 StatusText 是必须由派生类定义的属性,我会选择您显示的路线。

于 2009-05-19T14:50:35.240 回答
0

您可以选择的一种选择是将 Status 属性包装在基类中,以便它在更改中引发事件本身(在 C# 中,因为不知道 VB 并且目前无法访问 Visual Studio)

private string _status;

public string Status
{
    get { return _status; }
    protected set
    {
        if (_status == value) return;
        _status = value;
        StatusChanged(value);
    }
}
于 2009-05-19T15:05:28.627 回答
0

这是我的带有委托和状态文本参数的事件的代码

作为 StatusEventHandler 的公共事件状态

Protected Overridable Sub OnStatus(ByVal e As StatusEventArgs)
    RaiseEvent 状态(我,e)
结束子

Public Delegate Sub StatusEventHandler(ByVal sender As Object, _
   ByVal e 作为 StatusEventArgs)

<System.Serializable()> _
公共类 StatusEventArgs
    继承 System.EventArgs

    公共子新()
    结束子

    Public Sub New(ByVal statusText As String)
        _StatusText = 状态文本
    结束子

    ' 在此处输入事件属性等的代码。

    Private _StatusText As String = ""
    公共属性 StatusText() 作为字符串
        得到
            返回 _StatusText
        结束获取
        设置(ByVal 值作为字符串)
            _StatusText = 值
        结束集
    结束属性


结束类
于 2009-05-20T12:32:04.060 回答