2013-11-22 147 views
1

我很努力得到這個層次結構與泛型一起工作。問題是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" 
+0

等一下......我可能已經解決了它... – Tom

+0

不,我錯了,我認爲,通過對IItemHost指定BaseItem它會工作,但它意味着我不得不投SpecialItem的實例到CType(si,IItemHost(Of ExtraSpecialItem))。Items(用於訪問此對象上的Item)。 – Tom

回答

0

好吧,這並沒有完全解決問題,但它是我現在願意解決的解決方案。

如果我將BaseItem更改爲具有「BaseItems」集合,則我繼承的BaseGroup類可以具有默認Items 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 
+0

作爲進一步的補充,如果您使用Infragistics Grids之類的任何東西來綁定Items屬性(特別是如果它的層次很深,那很明顯),那麼使用BindingList(Of TGroup)而不是IEnumerable。我使用緩存的BindingList,當BaseItems.ListChanged被觸發時刷新。 – Tom