Does VB.Net's lack of implicit interfaces make what I'm trying to do impossible?
I know VB.Net does not allow implicit interface implementation like C#. And thus code like the following has no direct VB.Net correlation:
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
{
}
So the closest think I could think of in VB.Net is to do the following using the Shadows
keyword (since none of the operations are virtual):
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
Then I'm trying to use the wrapper as follows:
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()
Yet, of course this doesn't work (the event handler's are not executing), likely because I'm calling the base class for the RunWorkerAsync
and ReportProgress
methods, and the base class isn't using the Shadowed events. Thus, is there any way to achieve the same end result where the BackgroundWorker
implements an interface like in C#, but instead using explicit interface implementation for VB.Net?
UPDATE With Full Solution (Using Damien_The_Unbeliever's answer)
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)
开发者_Python百科 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
I think, as with the subs you've already shown, you need to pass all of your calls down to the same calls in the base class. The trickiest are the event handlers, but DoWork
can be implemented as:
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
And similarly for the other event handlers. In this way, event handlers added through your DoWork
event are actually added to your base classes DoWork
event.
精彩评论