Неужели отсутствие неявных интерфейсов в VB.Net делает невозможным то, что я пытаюсь сделать? - PullRequest
1 голос
/ 27 июня 2011

Я знаю, что 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

1 Ответ

3 голосов
/ 27 июня 2011

Я думаю, что, как и в случае с сабвуферами, которые вы уже показали, вам нужно передать все ваши вызовы тем же вызовам в базовом классе. Самыми хитрыми являются обработчики событий, но 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.

...