VB.Net缺乏隐式接口是否使我想做的事情变得不可能?
我知道VB.Net不允许像C#这样的隐式接口实现。 因此,如下代码没有直接的VB.Net相关性:
public interface IBackgroundWorkerAdapter { bool IsBusy { get; set; } bool WorkerReportsProgress { get; set; } bool WorkerSupportsCancellation { get; set; } event DoWorkEventHandler DoWork; event ProgressChangedEventHandler ProgressChanged; event RunWorkerCompletedEventHandler RunWorkerCompleted; void RunWorkerAsync(); void CancelAsync(); void ReportProgress(int progressPercent); void ReportProgress(int progressPercent, object userState); } public class BackgroundWorkerAdapter: BackgroundWorker, IBackgroundWorkerAdapter { }
因此,我在VB.Net中可以想到的最接近的想法是使用Shadows
关键字执行以下操作(因为没有任何操作是虚拟的):
Public Class BackgroundWorkerAdapter Inherits BackgroundWorker Implements IBackgroundWorkerAdapter Public Shadows ReadOnly Property IsBusy As Boolean _ Implements IBackgroundWorkerAdapter.IsBusy Get Return MyBase.IsBusy End Get End Property Public Shadows Property WorkerReportsProgress As Boolean _ Implements IBackgroundWorkerAdapter.WorkerReportsProgress Get Return MyBase.WorkerReportsProgress End Get Set(ByVal value As Boolean) MyBase.WorkerReportsProgress = value End Set End Property Public Shadows Property WorkerSupportsCancellation As Boolean _ Implements IBackgroundWorkerAdapter.WorkerSupportsCancellation Get Return MyBase.WorkerSupportsCancellation End Get Set(ByVal value As Boolean) MyBase.WorkerSupportsCancellation = value End Set End Property Public Shadows Event DoWork( ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) _ Implements IBackgroundWorkerAdapter.DoWork Public Shadows Event ProgressChanged( ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) _ Implements IBackgroundWorkerAdapter.ProgressChanged Public Shadows Event RunWorkerCompleted( ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) _ Implements IBackgroundWorkerAdapter.RunWorkerCompleted Public Sub New() MyBase.New() End Sub Public Shadows Sub CancelAsync() _ Implements IBackgroundWorkerAdapter.CancelAsync MyBase.CancelAsync() End Sub Public Shadows Sub ReportProgress(ByVal progressPercent As Integer) _ Implements IBackgroundWorkerAdapter.ReportProgress MyBase.ReportProgress(progressPercent) End Sub Public Shadows Sub ReportProgress( ByVal progressPercent As Integer, ByVal userState As Object) _ Implements IBackgroundWorkerAdapter.ReportProgress MyBase.ReportProgress(progressPercent, userState) End Sub Public Shadows Sub RunWorkerAsync() _ Implements IBackgroundWorkerAdapter.RunWorkerAsync MyBase.RunWorkerAsync() End Sub End Class
然后我尝试使用包装器如下:
Private ReadOnly _Worker As IBackgroundWorkerAdapter Public ReadOnly Property Worker() As IBackgroundWorkerAdapter Get Return _Worker End Get End Property ... AddHandler Me.Worker.DoWork, Sub() ... End Sub AddHandler Me.Worker.ProgressChanged, Sub(sender, e) Dim args = DirectCast(e, ProgressChangedEventArgs) ... End Sub AddHandler Me.Worker.RunWorkerCompleted, Sub() ... End Sub Me.Worker.RunWorkerAsync()
然而,当然这不起作用(事件处理程序没有执行),可能是因为我正在调用RunWorkerAsync
和ReportProgress
方法的基类,并且基类没有使用Shadowed事件。 因此,有没有办法实现相同的最终结果,其中BackgroundWorker
实现类似于C#的接口,而是使用VB.Net的显式接口实现?
完整解决方案更新(使用Damien_The_Unbeliever的答案)
Imports System.ComponentModel Public Class BackgroundWorkerAdapter Inherits BackgroundWorker Implements IBackgroundWorkerAdapter Public Shadows ReadOnly Property IsBusy As Boolean _ Implements IBackgroundWorkerAdapter.IsBusy Get Return MyBase.IsBusy End Get End Property Public Shadows Property WorkerReportsProgress As Boolean _ Implements IBackgroundWorkerAdapter.WorkerReportsProgress Get Return MyBase.WorkerReportsProgress End Get Set(ByVal value As Boolean) MyBase.WorkerReportsProgress = value End Set End Property Public Shadows Property WorkerSupportsCancellation As Boolean _ Implements IBackgroundWorkerAdapter.WorkerSupportsCancellation Get Return MyBase.WorkerSupportsCancellation End Get Set(ByVal value As Boolean) MyBase.WorkerSupportsCancellation = value End Set End Property Public Shadows Custom Event DoWork As DoWorkEventHandler _ Implements IBackgroundWorkerAdapter.DoWork AddHandler(ByVal value As DoWorkEventHandler) AddHandler MyBase.DoWork, value End AddHandler RemoveHandler(ByVal value As DoWorkEventHandler) RemoveHandler MyBase.DoWork, value End RemoveHandler RaiseEvent(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) MyBase.OnDoWork(e) End RaiseEvent End Event Public Shadows Custom Event ProgressChanged As ProgressChangedEventHandler _ Implements IBackgroundWorkerAdapter.ProgressChanged AddHandler(ByVal value As ProgressChangedEventHandler) AddHandler MyBase.ProgressChanged, value End AddHandler RemoveHandler(ByVal value As ProgressChangedEventHandler) RemoveHandler MyBase.ProgressChanged, value End RemoveHandler RaiseEvent(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) MyBase.OnProgressChanged(e) End RaiseEvent End Event Public Shadows Custom Event RunWorkerCompleted As RunWorkerCompletedEventHandler _ Implements IBackgroundWorkerAdapter.RunWorkerCompleted AddHandler(ByVal value As RunWorkerCompletedEventHandler) AddHandler MyBase.RunWorkerCompleted, value End AddHandler RemoveHandler(ByVal value As RunWorkerCompletedEventHandler) RemoveHandler MyBase.RunWorkerCompleted, value End RemoveHandler RaiseEvent(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) MyBase.OnRunWorkerCompleted(e) End RaiseEvent End Event Public Sub New() MyBase.New() End Sub Public Shadows Sub CancelAsync() _ Implements IBackgroundWorkerAdapter.CancelAsync MyBase.CancelAsync() End Sub Public Shadows Sub ReportProgress(ByVal progressPercent As Integer) _ Implements IBackgroundWorkerAdapter.ReportProgress MyBase.ReportProgress(progressPercent) End Sub Public Shadows Sub ReportProgress( ByVal progressPercent As Integer, ByVal userState As Object) _ Implements IBackgroundWorkerAdapter.ReportProgress MyBase.ReportProgress(progressPercent, userState) End Sub Public Shadows Sub RunWorkerAsync() _ Implements IBackgroundWorkerAdapter.RunWorkerAsync MyBase.RunWorkerAsync() End Sub End Class
我认为,就像你已经展示的潜艇一样,你需要将所有的呼叫传递给基类中的相同调用。 最棘手的是事件处理程序,但DoWork
可以实现为:
Public Shadows Custom Event DoWork As DoWorkEventHandler Implements IBackgroundWorkerAdapter.DoWork AddHandler(Value As DoWorkEventHandler) AddHandler MyBase.DoWork, Value End AddHandler RemoveHandler(Value As DoWorkEventHandler) RemoveHandler MyBase.DoWork, Value End RemoveHandler RaiseEvent(sender As Object, e As DoWorkEventArgs) MyBase.OnDoWork(e) End RaiseEvent End Event
对于其他事件处理程序也是如此。 通过这种方式,通过DoWork
事件添加的事件处理程序实际上已添加到基类DoWork
事件中。