如何在VB.NET中将实现类作为参数类型添加到接口的接口?

时间:2014-09-20 23:36:16

标签: vb.net interface

我想编写一个包含方法的接口,该方法具有与实现类相同类型的参数。

目前我正在使用此:

Public Interface IContent(Of T)
  Function ContentEquals(content As IContent(Of T)) As Boolean
End Interface

Public Class SpecificContent
  Implements IContent(Of Specific)

  Private m_Member As String

  Public Function ContentEquals(content As IContent(Of Specific)) As Boolean Implements IContent(Of Specific).ContentEquals
    ' Actually I need to access content.m_Member here
    ' Of course this doesn't work
    ' since not every IContent(Of Specific) has m_Member
    ' just because SpecificContent does.
    Return True
  End Function
End Class

问题是,这个接口定义需要ContentEquals的实现来接受实现IContent(Of Specific)的任何类型的任何对象,而不仅仅是SpecificContent实际上想要定义。

有没有办法在界面I中定义一个方法,该方法强制使用A的参数A Implements IB B Impements I的参数}, 一世。即类似于content As MyClass

2 个答案:

答案 0 :(得分:2)

不,没有。坦率地说,这是一件好事。

想一想 - 你怎么能使用这样的界面?接口的要点是,无论实际实现接口的对象的类型如何,都可以调用某个方法。如果接口包含绑定到其实现者类型的方法,那么您将在哪个类型的变量中存储该接口?如果你可以将它存储在变量中,你会如何将它传递给一个不了解impelementor的方法,只知道接口?该方法如何能够调用接口,它将作为参数传递什么?

对于这种等式测试,您应该覆盖Object.Equals方法,或引入明确接受您自己类型的Object.Equals的另一个重载。您仍然可以使用界面,但参数必须是Object类型,就像使用Object.Equals一样。

答案 1 :(得分:0)

我找到了实现我想要的正确方法。解决方案是接口继承,并且是您希望作为参数类型的类型的第二个通用。我知道我以前做过类似的事情,但它是用Java编写的,我不记得了。

这些是我的界面:

Public Interface IContentFactory(Of T, S As IContent(Of T))
  Function CreateFrom(obj As T) As IComparableContent(Of T, S)
End Interface

Public Interface IContent(Of T)
  Sub ApplyTo(obj As T)
End Interface

Public Interface IComparableContent(Of T, S As IContent(Of T))
  Inherits IContent(Of T)
  Function ContentEquals(content As S) As Boolean
End Interface

在我的代码中,我可以将这些接口用于通用内容处理类:

Public Class ContentHistory(Of T, S As IContent(Of T))
  Private m_Obj As T
  Private m_Factory As IContentFactory(Of T, S)

  Private m_History As Stack(Of IComparableContent(Of T, S))

  Public Sub New(obj As T, factory As IContentFactory(Of T, S))
    If obj Is Nothing Then Throw New ArgumentNullException("obj")
    If factory Is Nothing Then Throw New ArgumentNullException("factory")

    m_Obj = obj
    m_Factory = factory

    m_History = New Stack(Of IComparableContent(Of T, S))
  End Sub

  Public Sub Backup()
    Dim currentContent = m_Factory.CreateFrom(m_Obj)
    If m_History.Count = 0 OrElse Not m_History.Peek().ContentEquals(currentContent) Then
      m_History.Push(currentContent)
    End If
  End Function

  Private Sub Restore()
    If m_History.Count > 0 Then
      m_History.Pop().ApplyTo(m_Obj)
    End If
  End Function

End Class

现在我可以为内容对象及其工厂实现特定的类,如下所示:

Public Class SpecificContentFactory
  Implements IContentFactory(Of Specific, SpecificContent)

  Public Function CreateFrom(obj As Specific) As IComparableContent(Of Specific, SpecificContent) Implements IContentFactory(Of Specific, SpecificContent).CreateFrom
    Return New SpecificContent(obj)
  End Function
End Class

Public Class SpecificContent
  Implements IComparableContent(Of Specific, SpecificContent)

  Private ReadOnly m_Value As String

  Friend Sub New(obj As Specific)
    m_Value = obj.Value
  End Sub

  Public Sub ApplyTo(obj As Specific) Implements IContent(Of Specific).ApplyTo
    obj.Value = m_Value
  End Sub

  Public Function ContentEquals(content As SpecificContent) As Boolean Implements IComparableContent(Of Specific, SpecificContent).ContentEquals
    Return (content.m_Value = m_Value)
  End Function
End Class

要设置此内容处理程序,我所要做的就是

Dim obj = New Specific()
Dim history = New ContentHistory(Of Specific, SpecificContent)(obj, New SpecificContentFactory())

我可以像

一样使用它
obj.Value = "OldValue"
history.Backup
obj.Value = "OldValue"
history.Backup ' Nothing happens
obj.Value = "NewValue"
history.Backup
obj.Value = "EvenNewerValue"
Dim value = obj.Value ' "EvenNewerValue"
history.Restore
value = obj.Value ' "NewValue"
history.Restore
value = obj.Value ' "OldValue"
history.Restore ' Nothing happens
value = obj.Value ' "OldValue"

只要我提供SpecificContentSpecificContentFactory实施,我就可以将ContentHistory(Of Specific, SpecificContent)用于我喜欢的任何类型Specific