Вопрос

Хорошо, у меня есть базовый класс, который объявляет событие. 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
Это было полезно?

Решение

Я бы сказал, что вы довольно близки к рекомендуемому способу (или, по крайней мере, к тому, который я бы рекомендовал).

Я бы внес несколько изменений в ваш код, если бы был выбор:

  • Сделать статустекстизменед Protected Overridable
  • Оберните StatusText в собственный класс EventArgs.
  • Измените объявление 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.

Другие советы

Если у вашего дочернего класса нет особой необходимости переопределить метод базового класса, я бы сказал, что вызов реализации базового класса является абсолютно лучшим решением.

Это практически стандартный способ вызова событий базового класса через производный для сценариев такого типа.

Однако это может немного измениться в зависимости от того, кто контролирует StatusText для иерархии.Если в FooBase есть конкретное поле поддержки StatusText, которое можно изменить только с помощью средств доступа, то я бы не позволил дочернему элементу контролировать возникновение события StatusTextChanged.Вместо этого я бы принудительно вызывал события в установщике свойства StatusText.Это дает родительскому классу больше контроля над соблюдением любых контрактов, которые он хочет, когда следует и когда не вызывать указанное событие.

Однако если StatusText является свойством, которое должно быть определено производным классом, я бы выбрал отображаемый вами маршрут.

Одним из вариантов, который вы могли бы иметь, является оберните свойство статуса в базовом классе, так что оно поднимает само событие в изменении (в C#, как не знаю VB и в настоящее время не имеет доступа к Visual Studio))

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
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top