VB.Net继承和接口

时间:2011-07-14 14:24:29

标签: vb.net oop inheritance interface

有人暗示我在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

第三次演员不起作用。 为什么呢?

我是否错过了一堂课?

感谢

2 个答案:

答案 0 :(得分:1)

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


Brian的答案涵盖了协方面等等,我计划稍后在这个问题上添加的东西(我快速写了初始答案然后不得不离线 - 当我回来时,Brian已经回答)


回答先生。 moes comment - 想象一下如果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类型的对象

答案 1 :(得分:1)

强制转换不起作用,因为foobarISearch(Of ISearchResult)fooISearch(Of SearchResult,它们不兼容且不存在隐式转换运算符。

.NET 4.0引入了协变和逆变泛型类型参数的概念,可以用来优雅地解决这个问题。如果您尝试使用VB 10编译代码,则会出现此错误。

  

错误BC36757:'Module1.Search'无法转换为   'Module1.ISearch(Of Module1.ISearchResult)'。考虑改变'T'   在'Interface ISearch(Of T As。)的定义中   Module1.ISearchResult)'到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)的相同更改。