我只需要使用一个函数来处理包含接口类型的列表,以便可以为每个子类型重用它,但是在处理函数调用堆栈上方的列表项时,我还需要了解具体的类型:< / p>
LoadAItems
呼叫GetA
,后者呼叫FilterItems
。
FilterItems
必须是通用的,以便GetB
也可以调用和使用它。
问题是不允许尝试将子类型列表传递给常规的FilterItems
方法:
“无法将类型'List(Of AListItem)'转换为参数类型'List(Of IListItem)''
我尝试将列表中的每个AListItem对象转换为IListItem并将其添加到新列表中,但是问题是,FilterItems
函数应该从列表中删除元素。如果我从新列表中删除元素,则不会影响旧列表。我可以将其转换回去,但这只是为了使用该功能而造成的麻烦。
我不能仅将所有内容都更改为List(Of IListItem)
,因为那样的话,我将需要始终将FilterItems
或GetA
/ GetB
的返回值向下转换,因为{{1} } / LoadAItems
需要知道具体的类型。
我可以理解为什么强制转换不好,但是为什么不能强制转换具体类型正在实现的接口类型?
我已经尝试过:
LoadBItems
但这是不允许的:
“类型'List(Of AListItem)'的值不能转换为'List(Of IListItem)''
这是我的代码示例:
FilterItems(CType(items, List(Of IListItem))
答案 0 :(得分:3)
与其具有接受和操纵List(Of IListItem)
的功能,不如创建具有以下特征的功能:
Private Boolean IsGoodItem(IListItem)
希望您可以将FilterItems
中的现有代码直接转换为适合的代码。然后更改:
Public Function GetA() As List(Of AListItem)
Dim items As List(Of AListItem)
items = CallDatabase()
FilterItems(items) ' Does not allow!
Return items
End Function
收件人
Public Function GetA() As List(Of AListItem)
Dim items As List(Of AListItem)
items = CallDatabase()
Return items.Where(IsGoodItem).ToList()
End Function
您仍然可以(相当多地)重用代码,而不必担心协方差/协方差问题。 (我认为编译器会对Where
的类型推断感到满意,或者您可能必须在此处插入显式类型注释)
答案 1 :(得分:3)
如果我正确理解了您要执行的操作,则应该可以使函数本身具有通用性:
Private Sub FilterItems(Of T As IListItem)(items As List(Of T))
Of T As IListItem
添加了约束T
必须是IListItem
或从Public Function GetA() As List(Of AListItem)
Dim items As List(Of AListItem)
items = CallDatabase()
FilterItems(Of AListItem)(items)
Return items
End Function
Public Function GetB() As List(Of BListItem)
Dim items As List(Of BListItem)
items = CallDatabase()
FilterItems(Of BListItem)(items)
Return items
End Function
继承。
然后您可以这样称呼它:
<app-header></app-header>
<router-outlet></router-outlet>