包含子类项列表集合的类的VB.NET子类
考虑一个名为Fruit的类和一个名为FruitStand的类,该类包含一个通用的水果列表,并公开一个属性(Contents)来获取水果列表,以便在类中迭代水果 现在我想创建一个类Apple,它是水果的一个子类,我想创建一个名为AppleCart的类,它是水果摊的一个子类。AppleCart中泛型列表的内容将只包含Apple类的入口。我想要的是能够让AppleCart的消费者不必将Contents属性返回的元素从Fruit强制转换到Apple包含子类项列表集合的类的VB.NET子类,vb.net,list,subclass,generic-list,Vb.net,List,Subclass,Generic List,考虑一个名为Fruit的类和一个名为FruitStand的类,该类包含一个通用的水果列表,并公开一个属性(Contents)来获取水果列表,以便在类中迭代水果 现在我想创建一个类Apple,它是水果的一个子类,我想创建一个名为AppleCart的类,它是水果摊的一个子类。AppleCart中泛型列表的内容将只包含Apple类的入口。我想要的是能够让AppleCart的消费者不必将Contents属性返回的元素从Fruit强制转换到Apple 我希望这是一件简单的事情,我只是有一个心理障碍。您可以
我希望这是一件简单的事情,我只是有一个心理障碍。您可以对
水果摊
类使用一个通用约束,强制派生类在其声明中指定一个派生自水果的类
Sub Main()
Dim ac As New AppleCart({New Apple(), New Apple()})
For Each a In ac.Fruits
a.Rot() ' prints "The apple is rotten!"
Next
Console.Read()
End Sub
Public Class Fruit
Public Overridable Sub Rot()
Console.WriteLine("The fruit is rotten!")
End Sub
End Class
Public Class Apple
Inherits Fruit
Public Overrides Sub Rot()
Console.WriteLine("The apple is rotten!")
End Sub
End Class
Public Class FruitStand(Of T As Fruit)
Private _fruits As List(Of T)
Public ReadOnly Property Fruits As IEnumerable(Of T)
Get
Return _fruits
End Get
End Property
Public Sub New(fruits As IEnumerable(Of T))
_fruits = fruits.ToList()
End Sub
End Class
Public Class AppleCart
Inherits FruitStand(Of Apple)
Public Sub New(fruits As IEnumerable(Of Apple))
MyBase.New(fruits)
End Sub
End Class
你可以使用泛型
Sub Main()
Dim cart As New AppleCart
cart.Fruits.Add(New Apple)
End Sub
Class FruitStand(Of T As Fruit)
Public Property Fruits As List(Of T)
End Class
Class Fruit
End Class
Class AppleCart
Inherits FruitStand(Of Apple)
End Class
Class Apple
Inherits Fruit
End Class
我看到了3种选择:你要么让你的水果摊像这样通用:
Class FruitStand(Of TFruit As Fruit)
Public ReadOnly Property Contents As List(Of TFruit)
End Class
NotInheritable Class AppleCart
Inherits FruitStand(Of Apple)
End Class
或者您断开水果站
和AppleCart
之间的关系,而是从同一个新提取的基类派生它们(我认为这是最整洁的选项):
在这两种情况下,我都密封了派生的AppleCart
,因为从它派生的任何类型都无法覆盖TFruit
的类型。在层次结构中的该点,内容的类型
关闭
最后,您可以使用阴影来更改派生类型中内容的含义。问题是:您必须为基类型的内容
属性使用协变集合(这意味着使用只读接口,如IReadOnlyList(Of Fruit)
或数组-无论哪种方式,您都将失去添加或删除元素的能力):
如果AppleCart只能包含苹果,为什么有人要强制转换它呢?与其说AppleCart继承自水果摊,不如说一个接口(例如IFruitVendor(of T)
)可以满足您的需要。因为超类(水果摊)返回的是水果列表,而不是苹果列表。因此,消费者必须将枚举器返回的水果扔给苹果,才能访问苹果特有的属性。Apple Cart只包含苹果,因为它确保只有苹果被添加到列表中。我想到了类似IFruitVendor的东西,但我希望水果摊的逻辑成为类的一部分,而不需要在两个类中都复制。问题是,AppleCart仍然是一个水果摊,只是添加了一些功能——没有不同的功能。AppleCart只有在没有覆盖/重载返回项目的方法时才会返回水果。它们显然是通过AppleCart方法进入水果箱的,如果它们以同样的方式出来,它们就是ApplesI知道我遗漏了一些非常简单的东西。谢谢这三种方法都有优点。就我的目的而言,最简单的方法(使水果摊通用化)已经足够了,如荷花大学的答案所述。
MustInherit Class FruitStandBase(Of TFruit As Fruit)
Public ReadOnly Property Contents As List(Of TFruit)
End Class
NotInheritable Class FruitStand
Inherits FruitStandBase(Of Fruit)
End Class
NotInheritable Class AppleCart
Inherits FruitStandBase(Of Apple)
End Class
Class FruitStand
Public ReadOnly Property Contents As IReadOnlyList(Of Fruit)
Public Sub New()
Me.New(New List(Of Fruit))
End Sub
Protected Sub New(contents As IReadOnlyList(Of Fruit))
Me.Contents = contents
End Sub
End Class
Class AppleCart
Inherits FruitStand
Public Shadows ReadOnly Property Contents As IReadOnlyList(Of Apple)
Get
Return CType(MyBase.Contents, IReadOnlyList(Of Apple))
End Get
End Property
Public Sub New()
MyBase.New(New List(Of Apple))
End Sub
End Class