2011-07-14 73 views
1

有人提示我在VB.Net中做错了什么?VB.Net继承和接口

Module Module1 

Interface ISearch(Of T As ISearchResult) 
    Function ids() As List(Of T) 
End Interface 

Interface ISearchResult 
    Function id() As String 
End Interface 

MustInherit Class BasicSearch(Of T As ISearchResult) 
    Implements ISearch(Of T) 

    MustOverride Function ids() As System.Collections.Generic.List(Of T) Implements ISearch(Of T).ids 

End Class 

Class Search 
    Inherits BasicSearch(Of SearchResult) 
    Implements ISearch(Of SearchResult) 


    Overrides Function ids() As System.Collections.Generic.List(Of SearchResult) 
     Return New List(Of SearchResult) 
    End Function 
End Class 

Class SearchResult 
    Implements ISearchResult 
    Public Function id() As String Implements ISearchResult.id 
     Return "id" 
    End Function 
End Class 

Sub Main() 

    Dim foo As New Search() 
    Dim bar As Object = foo 
    Dim foobar As ISearch(Of ISearchResult) = foo 

End Sub 

End Module 

第三次演员不工作。 为什么?

我错过了一堂课?

感谢

回答

1

ISearch(Of SearchResult)不是ISearch(Of ISearchResult) - 他们有不同的泛型类型参数。 SearchISearch(Of SearchResult)


Brian的回答涵盖了协方差等,工具和.NET 4,我原本打算在以后添加到这个问题(我很快就写了最初的回答,然后不得不去下线 - 在我到达的时候布莱恩已回答)


回答先生,教育和体育评论 - 试想一下,如果ISearch有另一种方法:

Sub AddID(ID as T) 

,并假设接下来我们实现在Search(其中,记住,是ISearch(Of SearchResult),所以TSearchResult)。并假设我们有别的东西,它实现ISearchResult,说:现在

Public Class BadNews 
    Implements ISearchResult 

    Public Function id() As String Implements ISearchResult.id 
     Return "other" 
    Function 
End Class 

,如果你投的工作,我们现在可以称之为:

foobar.AddID(New BadNews) 

但这不能正常工作 - 的AddID的实现,我们打电话是由Search执行的那个 - 并且该功能仅期望接收SearchResult类型的对象。

+0

但我不能看到一个SearchResult作为ISearchResult,因为'Implements ISearchResult'? –

+0

@mr。 moe - 我试图添加一个如何出错的例子。 –

+0

这deffinetly帮助,但现在我不得不改变我的架构:D –

1

铸造不起作用,因为foobarISearch(Of ISearchResult)fooISearch(Of SearchResult这是不兼容的,并没有隐式转换操作符存在。

.NET 4.0引入了可用于优雅地解决这个问题的协变和逆变泛型类型参数的概念。如果你试图用VB 10编译代码,你会得到这个错误。

错误BC36757:'Module1.Search'can not be converted to 'Module1.ISearch(Of Module1.ISearchResult)'。考虑将'Interface ISearch(Of T As Module1.ISearchResult)'的定义中的'T' 更改为Out类型参数'Out T'。

下面你可以指出T是协变的ISearchResult通过使用新Out关键字的建议。

Interface ISearch(Of Out T As ISearchResult) 
    Function ids() As List(Of T) 
End Interface 

不幸的是,我们现在得到这个错误。

错误BC36724:类型'T'不能在此上下文中使用,因为'T'是 'Out'类型参数。

原因是因为List(Of T)本身并非协变。但是,IEnumerable(Of T)是。所以这会很好。

Interface ISearch(Of Out T As ISearchResult) 
    Function ids() As IEnumerable(Of T) 
End Interface 

你会那么需要从List(Of T)相同的变化IEnumerable(Of T)为其他申报为好。

+0

可悲的是我必须vb.net 3.5 –