简体   繁体   English

基类中的事件

[英]Events in Base Classes

Ok, so I have a base class which declares the event StatusTextChanged . 好的,所以我有一个基类,它声明事件StatusTextChanged My child class, of course cannot directly raise this event. 我的孩子上课当然不能直接引发这一事件。

So I wind up with something like this (for simplicity sake): 因此,我得出这样的结论(为简单起见):

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

And then in the child class I call MyBase.RaiseStatusTextChangedEvent("something") . 然后在子类中,我调用MyBase.RaiseStatusTextChangedEvent("something") Is there a better or more recommended way to do this? 是否有更好或更推荐的方法来做到这一点?

edit: VB.NET or C#, either way it works essentially the same. 编辑:VB.NET或C#,无论哪种方式,其工作原理基本相同。

edit: So after the responses, I'm at this in the base class, then just set the StatusText property in the child class ... 编辑:所以在响应后,我在基类中,然后在子类中设置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

I would say that you are rather close to the recommeneded way (or at least the one I would recommend). 我要说的是,您非常接近推荐的方式(或者至少是我建议的方式)。

I would make a few alterations to your code, given a choice: 如果可以选择的话,我将对您的代码进行一些更改:

  • Make StatusTextChanged Protected Overridable 使StatusTextChanged Protected Overridable
  • Wrap StatusText in a custom EventArgs class 将StatusText包装在自定义EventArgs类中
  • Change the StatusTextChanged declaration into Public Event StatusTextChanged As EventHandler(Of YourCustomEventArgs) 将StatusTextChanged声明更改为Public Event StatusTextChanged As EventHandler(Of YourCustomEventArgs)

The resulting code: 结果代码:

The custom eventargs class: 自定义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

The event implementation in your base class: 基类中的事件实现:

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

...and finally a code line for raising the event; ...最后是引发事件的代码行; either in the base class or a class that inherits it: 在基类或继承它的类中:

OnStatusTextChanged(New TextEventArgs("some text"))

This will be more in line with how events are designed within the rest of the .NET framework. 这将与.NET框架其余部分中事件的设计方式更加一致。

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

This is pretty much the standard way for raising events on a base class via a derived one for this type of scenario. 这几乎是通过此类场景的派生事件在基类上引发事件的标准方法。

However this could change a bit depending on who is in control of the StatusText for the hierarchy. 但是,这可能会有所变化,具体取决于谁控制层次结构的StatusText。 If there is a concrete StatusText backing field in FooBase which can only be changed via accessors, then I would not let the child control the raising of the StatusTextChanged event. 如果FooBase中有一个具体的StatusText支持字段,只能通过访问器进行更改,那么我将不让孩子控制StatusTextChanged事件的引发。 Instead I would force the raising of the events within the Setter of the property for StatusText. 相反,我将强制在StatusText属性的Setter中引发事件。 This gives the parent class more control in enforcing any contracts it wants around when to and when not to raise said event. 这使父类在执行它想要何时以及何时不引发该事件的任何合同时具有更多的控制权。

However if the StatusText is a property which must be defined by the derived class, I would choose the route you displayed. 但是,如果StatusText是必须由派生类定义的属性,我将选择您显示的路由。

One option you could have is wrap the Status property in the base class, so that it raises the event itself in a change (in C# as dont know VB and dont have access to Visual Studio at the moment) 您可能拥有的一种选择是将Status属性包装在基类中,以便它在更改中引发事件本身(在C#中,因为不知道VB,并且目前无法访问Visual Studio)

private string _status;

public string Status
{
    get { return _status; }
    protected set
    {
        if (_status == value) return;
        _status = value;
        StatusChanged(value);
    }
}

Here's My code for an event with a delegate and a parameter of status text 这是带有委托和状态文本参数的事件的“我的代码”

Public Event Status As StatusEventHandler

Protected Overridable Sub OnStatus(ByVal e As StatusEventArgs)
    RaiseEvent Status(Me, e)
End Sub

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

<System.Serializable()> _
Public Class StatusEventArgs
    Inherits System.EventArgs

    Public Sub New()
    End Sub

    Public Sub New(ByVal statusText As String)
        _StatusText = statusText
    End Sub

    ' Enter code here for event properties, etc.

    Private _StatusText As String = ""
    Public Property StatusText() As String
        Get
            Return _StatusText
        End Get
        Set(ByVal value As String)
            _StatusText = value
        End Set
    End Property


End Class

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM