6

不是一个家庭作业问题,尽管场景很奇怪。我刚刚替换了我正在使用的真实对象来简化示例。

让我从这里开始,但不确定如何继续。我正在尝试编写一个包含集合的类,而我迷失在 and 的世界中IEnumeratorIEnumerable我对它很陌生(甚至不完全确定我走在正确的道路上)。假设我有一堂课:

Public Class BakedBean
    Private Shape As String
    Private Variety As String
    Private Flavour As String
    'etc
End Class

另一个代表BakedBeans 集合的类:

Public Class TinOfBeans
    '?
End Class

我希望能够以集合的形式Beans进入TinOfBeans课堂,这样我就可以进行这样的调用,但不会被绑定到特定的集合类型:

Dim myTin As New TinOfBeans()
myTin.Add(New BakedBean(...))

For Each bean As BakedBean in myTin
    '...
Next

myTin(0).Flavour = "beany"

我一直在看IEnumerableand IEnumerator,到目前为止我有这么多,但我对它感到非常迷茫:

烤豆类

Public Class BakedBean
    Private Shape As String
    Private Variety As String
    Private Flavour As String
    'etc
End Class

BeansEnumerator 类

Public Class BeansEnumerator
    Implements IEnumerator

    Private Position As Integer = -1

    Public ReadOnly Property Current As Object Implements System.Collections.IEnumerator.Current
        Get
            '???
        End Get
    End Property

    Public Function MoveNext() As Boolean Implements System.Collections.IEnumerator.MoveNext
        '???
    End Function

    Public Sub Reset() Implements System.Collections.IEnumerator.Reset
        Position = -1
    End Sub
End Class

TinOfBeans 类

Public Class TinOfBeans
    Implements IEnumerable

    Private beansEnum As BeansEnumerator

    Public Function GetEnumerator() As System.Collections.IEnumerator Implements System.Collections.IEnumerable.GetEnumerator
            Return beansEnum
    End Function
End Class

在这一点上,我陷入了困境,不知道如何进行(或者,正如我在开始时所说,如果这甚至是正确的方法)。有什么建议么?

4

2 回答 2

7

你这样做太难了。.Net已经通过使用泛型提供了您需要的确切类。

我希望能够......拨打这样的电话:

Dim myTin As New TinOfBeans()
myTin.Add(New BakedBean(...))

For Each bean As BakedBean in myTin
    '...
Next

myTin(0).Flavour = "beany"

当然。就是这样:

Dim myTin As New List(Of BakedBean)()
myTin.Add(New BakedBean(...))

For Each bean As BakedBean in myTin 
   '...
Next

myTin(0).Flavour = "beany"

你的每一行都准确地映射。让通用集合为您完成工作。

您似乎也对此感到困惑IEnumerable,我还有一个要求要实现:

拨打电话...不绑定到特定的集合类型

我们可以用一种技术覆盖这两种情况。让我们定义一个接受 Bean 集合的方法:

Public Sub CookBeans(ByVal beans As List(Of BakedBean))

但是,这不处理数组、迭代器或其他 BakedBean 集合类型。这里的答案是 IEnumerable:

Public Sub CookBeans(BvVal beans As IEnumerable(Of BakedBean))
   For Each bean As BakedBean In beans
      Cook(bean)
   Next 
End Sub

这次我包含了该方法的示例实现,以便您了解它是如何工作的。这里要理解的重要一点是,此方法将允许您调用它并传递一个 Array、List、Iterator 或任何其他 BakedBean 集合。

这是有效的,因为 aList(Of BakedBean) (或者更确切地说,实现了) a IEnumerable(Of BakedBean)。BakedBean 数组和其他 .Net 集合也是如此。IEnumerable 是所有集合的根接口。您可以在内存中的某处拥有一个具体的 List(Of BakedBean) 对象,但使用 定义您的方法参数和返回类型IEnumerable(Of BakedBean),如果您决定将该 List 对象更改为其他对象,这些方法仍然可以工作。

您还可以返回 IEnumerable:

Public Function GetPintos(ByVal beans As IEnumerable(Of BakedBean)) As IEnumerable(Of BakedBean)
    Dim result As IEnumerable(Of BakedBean)
    result = beans.Where(Function(bean) bean.Variety = "pinto")
    Return result
End Function

如果你需要 IEnumerable 成为一个列表,这很容易:

Dim beans As List(Of BakedBeans) = '... get beans from somewhere

Dim pintos As List(Of BakedBeans) = GetPintos(beans).ToList()
Cook(pintos)
于 2013-10-29T14:23:53.100 回答
1

我想你可能会有点复杂。除非你真的想学习如何使用 IEnumerable,否则你只需要继承一个列表。

Public Class TinOfBeans
    Inherits List(Of BakedBean)

End Class

或者在 Tin 中有一个列表

Public Class TinOfBeans
    Public Property Beans As New List(Of BakedBean)

End Class
于 2013-10-29T14:05:05.520 回答