Eventos de base classes
-
22-08-2019 - |
Pergunta
Ok, então eu tenho uma classe base que declara a StatusTextChanged
evento. Minha classe criança, claro que não pode levantar directamente este evento.
Então eu acabar com algo parecido com isso (por causa da simplicidade):
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
E, em seguida, na chamada de classe criança
MyBase.RaiseStatusTextChangedEvent("something")
.
Existe uma maneira melhor ou mais recomendada para fazer isso?
edit:. VB.NET ou C #, de qualquer forma ele funciona essencialmente o mesmo
edit: Então, depois de as respostas, eu estou neste na classe base, em seguida, basta definir a propriedade StatusText na classe criança ...
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
Solução
Eu diria que você é bastante próxima à maneira recommeneded (ou pelo menos o que eu recomendaria).
Gostaria de fazer algumas alterações ao seu código, dada uma escolha:
- Faça StatusTextChanged
Protected Overridable
- Enrole StatusText em uma classe EventArgs personalizados
- Alterar a declaração StatusTextChanged em
Public Event StatusTextChanged As EventHandler(Of YourCustomEventArgs)
O código resultante:
A classe EventArgs personalizados:
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
A implementação evento em sua classe base:
Public Event StatusTextChanged As EventHandler(Of TextEventArgs)
Protected Overridable Sub OnStatusTextChanged(ByVal e As TextEventArgs)
RaiseEvent StatusTextChanged(Me, e)
End Sub
... e, finalmente, uma linha de código para disparar o evento; quer na classe base ou uma classe que herda-lo:
OnStatusTextChanged(New TextEventArgs("some text"))
Este será mais em linha com a forma como os eventos são projetados dentro do resto do framework .NET.
Outras dicas
A menos que haja uma necessidade específica para sua classe filho para substituir um método classe base, então eu diria que chamar a implementação de classe base é absolutamente a melhor solução.
Isso é muito bonito a forma padrão para a criação de eventos em uma classe base via um derivado para este tipo de cenário.
No entanto, isto poderia mudar um pouco dependendo de quem está no controle do StatusText para a hierarquia. Se houver um concreto StatusText campo de backup em FooBase que só pode ser alterado por meio de assessores, então eu não iria deixar o controle filho a elevação do evento StatusTextChanged. Em vez disso eu iria forçar o aumento dos eventos dentro do setter da propriedade para StatusText. Isto dá a classe pai mais controle na aplicação de quaisquer contratos que quer em torno de quando e quando não levantar referido evento.
No entanto, se o StatusText é uma propriedade que deve ser definido pela classe derivada, eu escolheria a rota que você exibido.
Uma opção que você pode ter é envolver a propriedade Estado na classe base, de modo que ele levanta o próprio evento em uma mudança (Em C # como Não sei VB e não tem acesso ao Visual Studio no momento)
private string _status;
public string Status
{
get { return _status; }
protected set
{
if (_status == value) return;
_status = value;
StatusChanged(value);
}
}
Aqui está o meu código para um evento com um delegado e um parâmetro de texto de status
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