是否VB.Net缺乏隐含接口做什么,我试图做不可能的? [英] Does VB.Net's lack of implicit interfaces make what I'm trying to do impossible?
问题描述
我知道VB.Net不允许像C#的隐式接口的实现。因而,如下面的代码并没有直接的相关性VB.Net:
公共接口IBackgroundWorkerAdapter
{
布尔IsBusy {搞定;组; }
布尔WorkerReportsProgress {搞定;组; }
布尔WorkerSupportsCancellation {搞定;组; }
事件DoWorkEventHandler DoWork的;
事件ProgressChangedEventHandler ProgressChanged;
事件RunWorkerCompletedEventHandler RunWorkerCompleted;
无效的RunWorkerAsync();
无效CancelAsync();
无效ReportProgress(INT progressPercent);
无效ReportProgress(INT progressPercent,对象userState);
}
公共类BackgroundWorkerAdapter:BackgroundWorker的,IBackgroundWorkerAdapter
{
}
所以最接近认为我能想到的在VB.Net是做以下使用阴影
关键字(因为没有操作的都是虚拟的):
公共类BackgroundWorkerAdapter
继承BackgroundWorker的
实现IBackgroundWorkerAdapter
公共阴影只读属性IsBusy由于布尔_
实现IBackgroundWorkerAdapter.IsBusy
得到
返回MyBase.IsBusy
端获取
高端物业
酒店的公共财产阴影作为WorkerReportsProgress布尔_
实现IBackgroundWorkerAdapter.WorkerReportsProgress
得到
返回MyBase.WorkerReportsProgress
端获取
组(BYVAL值作为布尔)
MyBase.WorkerReportsProgress =价值
端设置
高端物业
公共财产阴影作为WorkerSupportsCancellation布尔_
实现IBackgroundWorkerAdapter.WorkerSupportsCancellation
得到
返回MyBase.WorkerSupportsCancellation
端获取
组(BYVAL值作为布尔)
MyBase.WorkerSupportsCancellation =价值
端设置
高端物业
酒店的公共事件阴影DoWork的(
BYVAL发件人为对象,
BYVAL E上System.ComponentModel.DoWorkEventArgs)_
实现IBackgroundWorkerAdapter.DoWork
公共事件的阴影ProgressChanged(
BYVAL发件人为对象,
BYVAL E上System.ComponentModel.ProgressChangedEventArgs)_
实现IBackgroundWorkerAdapter.ProgressChanged
公共事件的阴影RunWorkerCompleted(
BYVAL发件人为对象,
BYVAL E上System.ComponentModel.RunWorkerCompletedEventArgs)_
实现IBackgroundWorkerAdapter.RunWorkerCompleted
的Public Sub New()
MyBase.New()
端子
公共阴影子CancelAsync()_
实现IBackgroundWorkerAdapter.CancelAsync
MyBase.CancelAsync()
端子
公共阴影子ReportProgress(BYVAL progressPercent作为整数)_
实现IBackgroundWorkerAdapter.ReportProgress
MyBase.ReportProgress(progressPercent)
端子
公共阴影子ReportProgress(
BYVAL progressPercent整数,
BYVAL userState作为对象)_
实现IBackgroundWorkerAdapter.ReportProgress
MyBase.ReportProgress(progressPercent,userState)
端子
公共阴影子的RunWorkerAsync()_
实现IBackgroundWorkerAdapter.RunWorkerAsync
MyBase.RunWorkerAsync()
端子
端类
然后我试图使用包装如下:
私人只读_Worker为)IBackgroundWorkerAdapter
公共只读属性,工人(由于IBackgroundWorkerAdapter
得到
返回_Worker
端获取
高端物业
...
的AddHandler Me.Worker.DoWork,
子()
:
端子
的AddHandler Me.Worker.ProgressChanged,
子(发件人,E)
尺寸ARGS = DirectCast(即ProgressChangedEventArgs)
:
端子
AddHandler的Me.Worker.RunWorkerCompleted,
子()
:
端子
Me.Worker.RunWorkerAsync()
不过,当然因为我呼吁基类这不起作用(事件处理程序的未执行),可能的RunWorkerAsync
和 ReportProgress
方法,基类不使用阴影事件。 因此,有没有什么办法来实现,其中的BackgroundWorker
实现一个接口象在C#中,而是使用显式接口实现对VB.Net相同的最终结果?
更新完整的解决方案 (使用Damien_The_Unbeliever的答案) 子>
进口System.ComponentModel
类公共BackgroundWorkerAdapter
继承BackgroundWorker的
器具IBackgroundWorkerAdapter
公共阴影只读属性IsBusy由于布尔_
实现IBackgroundWorkerAdapter.IsBusy
得到
返回MyBase.IsBusy
端获取
高端物业
公共财产阴影作为WorkerReportsProgress布尔_
实现IBackgroundWorkerAdapter.WorkerReportsProgress
得到
返回MyBase.WorkerReportsProgress
端获取
组( BYVAL值作为布尔)
MyBase.WorkerReportsProgress =价值
端设置
高端物业
公共财产阴影作为WorkerSupportsCancellation布尔_
实现IBackgroundWorkerAdapter.WorkerSupportsCancellation
得到
返回MyBase.WorkerSupportsCancellation
端获取
组(BYVAL值作为布尔)
MyBase.WorkerSupportsCancellation =价值
端设置
高端物业
公共阴影自定义事件的DoWork作为DoWorkEventHandler _
实现IBackgroundWorkerAdapter.DoWork
的AddHandler(BYVAL值作为DoWorkEventHandler)
的AddHandler MyBase.DoWork,价值
端的AddHandler
RemoveHandler(BYVAL值作为DoWorkEventHandler)
RemoveHandler MyBase.DoWork,价值
端RemoveHandler
的RaiseEvent(BYVAL发件人为对象,BYVAL E上System.ComponentModel.DoWorkEventArgs)
MyBase.OnDoWork(五)
端的RaiseEvent
端事件
公共阴影自定义事件ProgressChanged作为ProgressChangedEventHandler _
实现IBackgroundWorkerAdapter.ProgressChanged
的AddHandler(BYVAL值作为ProgressChangedEventHandler)
的AddHandler MyBase.ProgressChanged,价值
端的AddHandler
RemoveHandler(BYVAL值作为ProgressChangedEventHandler)
RemoveHandler MyBase.ProgressChanged,价值
端RemoveHandler
的RaiseEvent(BYVAL发件人为对象,BYVAL E上System.ComponentModel.ProgressChangedEventArgs)
MyBase.OnProgressChanged( E)
端的RaiseEvent
端事件
公共阴影自定义事件RunWorkerCompleted作为RunWorkerCompletedEventHandler _
实现IBackgroundWorkerAdapter.RunWorkerCompleted
的AddHandler(BYVAL值由于RunWorkerCompletedEventHandler)
的AddHandler MyBase.RunWorkerCompleted,价值
端的AddHandler
RemoveHandler(BYVAL值作为RunWorkerCompletedEventHandler)
RemoveHandler MyBase.RunWorkerCompleted,价值
端RemoveHandler
的RaiseEvent(BYVAL发件人为对象,BYVAL E上System.ComponentModel.RunWorkerCompletedEventArgs)
MyBase.OnRunWorkerCompleted(五)
端的RaiseEvent
端事件
的Public Sub New()
MyBase.New()
端子
公共阴影子CancelAsync()_
实现IBackgroundWorkerAdapter.CancelAsync
MyBase.CancelAsync()
端子
公共阴影子ReportProgress(BYVAL progressPercent作为整数)_
实现IBackgroundWorkerAdapter.ReportProgress
MyBase.ReportProgress(progressPercent)
端子
公共阴影子ReportProgress(
BYVAL progressPercent整数,
BYVAL userState作为对象)_
实现IBackgroundWorkerAdapter.ReportProgress
MyBase .ReportProgress(progressPercent,userState)
端子
公共阴影子的RunWorkerAsync()_
实现IBackgroundWorkerAdapter.RunWorkerAsync
MyBase.RunWorkerAsync()
端子
端类
我想,与你已经显示的潜艇,你需要通过所有来电到基类相同的调用。最棘手的是事件处理程序,但的DoWork
可以作为实现:
<预类=朗动prettyprint-覆盖>
公共阴影自定义事件的DoWork作为DoWorkEventHandler器具IBackgroundWorkerAdapter.DoWork
的AddHandler(价值DoWorkEventHandler)
的AddHandler MyBase.DoWork,价值
端的AddHandler
RemoveHandler(价值DoWorkEventHandler)
RemoveHandler MyBase.DoWork,价值
端RemoveHandler
的RaiseEvent(发送者为对象,E作为DoWorkEventArgs)
MyBase.OnDoWork (五)
端的RaiseEvent
端事件
和类似的其他事件处理程序。通过这种方式,事件处理程序通过的DoWork
事件增加实际上是添加到您的基类的DoWork
事件。
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)
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.
这篇关于是否VB.Net缺乏隐含接口做什么,我试图做不可能的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!