Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vb.net/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 基类中的事件_.net_Vb.net_Events_Derived Class - Fatal编程技术网

.net 基类中的事件

.net 基类中的事件,.net,vb.net,events,derived-class,.net,Vb.net,Events,Derived Class,好的,我有一个基类,它声明事件StatusTextChanged。我的孩子班,当然不能直接提出这个事件 所以我最终得到了这样的结果(为了简单起见): 然后在儿童课上我打电话给 MyBase.RaiseStatusTextChangedEvent(“某物”)。 有没有更好或更推荐的方法 编辑:VB.NET或C#,两者的工作原理基本相同 编辑:所以在回答之后,我在基类中处理这个问题,然后在子类中设置StatusText属性 Public Event StatusTextChanged(ByV

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

所以我最终得到了这样的结果(为了简单起见):

然后在儿童课上我打电话给
MyBase.RaiseStatusTextChangedEvent(“某物”)
。 有没有更好或更推荐的方法

编辑: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

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

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

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


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

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

如果有选择,我会对您的代码进行一些修改:

  • 使StatusTextChanged
    Protected可重写
  • 在自定义EventArgs类中包装StatusText
  • 将StatusTextChanged声明更改为
    Public Event StatusTextChanged As EventHandler(属于CustomEventArgs)
生成的代码:

自定义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 framework其余部分中事件的设计方式。

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


下面是我的代码,它包含一个委托和一个状态文本参数

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 公共事件状态为StatusEventHandler 受保护的可重写子状态(通过值e作为StatusEventArgs) RaiseEvent状态(Me、e) 端接头 公共委托子StatusEventHandler(ByVal发送方作为对象_ ByVal e作为StatusEventArgs) _ 公共类StatusEventArgs 继承System.EventArgs 公共分新() 端接头 Public Sub New(ByVal statusText作为字符串) _StatusText=StatusText 端接头 '在此处输入事件属性等的代码。 Private _statustextas String=“” 公共属性StatusText()作为字符串 得到 返回状态文本 结束 设置(ByVal值作为字符串) _状态文本=值 端集 端属性 末级
澄清一下,你是说我这样做是最好的解决方案?似乎有点多余的代码。对此没有重写,至少不是我喜欢的,但我不能声明它不可重写,因为它没有重写基方法(它在基类中)。我应该澄清这个问题吗?是的,在我看来,它是明确的,比任何其他实现都更易于维护。该方法存在于基类中,您不会在子类中向其添加任何内容,因此请显式地调用基类:)状态文本没有属性,甚至没有变量。我真的不想暴露它。虽然我可以为状态文本设置一个受保护的getter/setter,但这似乎也是多余的代码。当然,事件处理程序的.NET标准是子事件处理程序(发送方作为System.Object,e作为System.EventArgs),基本上我只是为了文章的简洁而简化了一些事情。不过,如果只从子类引发基类事件就好了。看起来还是有点多余的代码。到目前为止,您的答案是最好的。正如Fredrik所指出的,您提出的方法非常接近.NET Framework标准。查看System.Windows.Forms.TextBox,您将看到许多受保护的虚拟方法(OnTextChanged等)。正是出于此目的,可重写位是完全可选的ofc,仅当您需要更改子类中的行为时才需要。不过,在我看来,您的示例代码中缺少一行。。这与引发事件的问题本身无关,但为了完整起见,您可能应该在“Set(ByVal value as String)”行之后插入一个“_StatusText=value”。事实上,甚至可以用“If value\u StatusText Then”等形式将其全部包装起来。。要确保在状态文本实际更改之前不会引发StatusTextChanged事件,请执行以下操作:)
private string _status;

public string Status
{
    get { return _status; }
    protected set
    {
        if (_status == value) return;
        _status = value;
        StatusChanged(value);
    }
}
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