将通用接口转换为基类型

时间:2013-11-22 12:16:27

标签: vb.net generics casting

我正在努力让这个层次结构与泛型一起工作。问题是Items是通用的,在继承级别指定,因此我无法强制转换为BaseItem,即当SpecialItem继承BaseGroup时,从SpecialItem(Of ExtraSpecialItem)转换为IItemHost(Of BaseItem),因为BaseGroup实现了IItemHost。

我在这里做错了什么?

Public MustInherit Class BaseItem
    Public Property ItemNameOrSomething As String
End Class

Public Interface IItemHost(Of TItemType As {BaseItem})
    Property Items As BindingList(Of TItemType) '-- No Out parameter allowed :(
End Interface

Public Class BaseGroup(Of TGroup AS {BaseItem})
    Inherits BaseItem
    Implements IItemHost(Of TGroup)

    '-- This is the key property, all BaseGroup implimentors need an Items property of their specific type
    Public Property Items As New BindingList(Of TGroup)() Implements IItemHost(Of TGroup).Items

End Class

Public Class SpecialItem
    Inherits BaseGroup(Of ExtraSpecialItem)

End Class

Public Class ExtraSpecialItem
    Inherits BaseGroup(Of LeafItem)

End Class

Public Class LeafItem
    Inherits BaseItem

End Class

在大多数情况下,这一切都有效。我不能做的是:

Dim root = New SpecialItem()
root.ItemNameOrSomething = "Testing 1"
root.Items.Add(New ExtraSpecialItem() With {.ItemNameOrSomething = "Testing 2"})

'-- This specifically, no casting options available.
Dim item = CType(root, IItemHost(Of BaseItem))
Dim subItems = item.Items
Dim testing2Text = subItems.First().ItemNameOrSomething '-- = "Testing 2"

1 个答案:

答案 0 :(得分:0)

好的,这并没有完全解决问题,但这是我现在愿意和解的解决方案。

如果我将BaseItem更改为具有“BaseItems”集合,则我继承的BaseGroup类可以具有默认项IEnumerable。如果我需要回写这个集合,我可以简单地使用BaseItems。对于标准循环项目,我可以使用项目,这将给我正确的投射。

Public MustInherit Class BaseItem

    Public Property ItemNameOrSomething As String
    Public Property BaseItems As New BindingList(Of BaseItem)()

End Class

Public Class BaseGroup(Of TGroup As {BaseItem})
    Inherits BaseItem

    Public ReadOnly Property Items As IEnumerable(Of TGroup)
        Get
            Return BaseItems.Cast(Of TGroup)()
        End Get
    End Property

End Class