通用集合

时间:2009-04-28 15:37:56

标签: vb.net

在VB6中,曾经有一个Collection数据类型,它允许通过其键或序号检索集合中的项目。但是,它没有强类型。

现在,使用VB.Net,我正在寻找一个强类型的合适替代品,可以与泛型集合一起使用。

这是我想要做的一个简单的例子。唯一的问题是底层集合类BindingList不支持通过alpha键有效地检索项目,因此我必须循环遍历元素以获取我正在寻找的项目。对于大型馆藏,这效率不高。

我查看了各种Collection类型,但没有找到合适的替代品。

这是我想要做的,除了使用Item属性完成的循环。

如果可以的话,请不要只是说“使用哈希表”或类似的内容,请详细说明我在下面的简短示例中所做的详细说明。

Public Class Car

    Public Sub New(ByVal keyName As String, ByVal property1 As String)
        _KeyName = keyName
        _Property1 = property1
    End Sub

    Dim _KeyName As String

    Public Property KeyName() As String
        Get
            Return _KeyName
        End Get
        Set(ByVal value As String)
            _KeyName = value
        End Set
    End Property

    Public _Property1 As String

    Public Property Property1() As String
        Get
            Return _Property1
        End Get
        Set(ByVal value As String)
            _Property1 = value
        End Set
    End Property

End Class

Public Class Cars

    Inherits System.ComponentModel.BindingList(Of Car)

    Public Overloads ReadOnly Property Item(ByVal key As String) As Car
        Get
            For Each CurrentCar As Car In Me.Items
                If CurrentCar.KeyName = key Then
                    Return CurrentCar
                End If
            Next
            Return Nothing
        End Get
    End Property

End Class

4 个答案:

答案 0 :(得分:4)

我相信你正在寻找Dictionary<TKey, TValue>。实际上,如果您确实希望自己的集合类具有强类型且不是(本身)通用的,那么如果将父类更改为Dictionary<string, Car>,则应该全部设置。当然,这一切都假设您使用显式字符串键将汽车添加到集合中。如果您希望查找基于集合中属性的值,那么您最好使用或继承List<Car>并使用LINQ查询列表。然后你可以......

Public Overloads ReadOnly Property Item(ByVal key As String) As Car
    Get
        Return (from c in Me where c.KeyName = key select c).SingleOrDefault()
    End Get
End Property

答案 1 :(得分:0)

你真的需要通过密钥AND索引进行访问吗?

如果不这样做,则使用Dictionary(Of String,Car),然后使用 - MyCol.Items("XXX")按键检索项目(或简写MyCol(“XXX”)) - MyCol.ContainsKey("XXX")来测试集合中是否存在密钥 - 如果要枚举所有对象及其键,请在MyCol中For Each Entry as KeyValuePair(Of String, Car) - 对于MyCol.Values中的每个条目作为Car,如果要在不考虑密钥的情况下枚举条目

如果您需要通过索引和密钥进行访问,我担心最好的办法是使用List(of Car)和Dictionary(of Car)滚动到一个自定义集合类中,因为我相信它们离开了那种对大多数问题都没有用的收藏品。

答案 2 :(得分:0)

我认为这是我最好的解决方案。我欢迎评论更好的方式!

Imports Microsoft.VisualBasic



Public Class Car

    Implements Xs(Of Car).IKeyName

    Private _KeyName As String

    Public Sub New(ByVal keyName As String, ByVal property1 As String)
        _KeyName = keyName
        _Property1 = property1
    End Sub

    Public Property KeyName() As String Implements Xs(Of Car).IKeyName.KeyName
        Get
            Return _KeyName
        End Get
        Set(ByVal value As String)
            _KeyName = value
        End Set
    End Property

    Public _Property1 As String

    Public Property Property1() As String
        Get
            Return _Property1
        End Get
        Set(ByVal value As String)
            _Property1 = value
        End Set
    End Property

End Class

Public Class Cars

    Inherits System.ComponentModel.BindingList(Of Car)

    Public Overloads ReadOnly Property Item(ByVal key As String) As Car
        Get
            For Each CurrentCar As Car In Me.Items
                If CurrentCar.KeyName = key Then
                    Return CurrentCar
                End If
            Next
            Return Nothing
        End Get
    End Property

End Class

Public Class X

    Private _KeyName As String

    Public Property KeyName() As String
        Get
            Return _Keyname
        End Get
        Set(ByVal value As String)
            _Keyname = value
        End Set
    End Property
End Class

Public Class Xs(Of X)

    Inherits Hashtable

    Interface IKeyName
        Property KeyName() As String
    End Interface

    Public Shadows Sub Add(ByVal item As IKeyName)
        MyBase.Add(item.KeyName, item)
    End Sub

    Public Shadows ReadOnly Property Item(ByVal key As String) As x

        Get
            If Me.ContainsKey(key) Then
                Return MyBase.Item(key)
            Else
                'If I mispell a key, I don't want to end up creating a new mispelled version, I want an error
                Throw New Exception("Element with key " & key & " is not found")
            End If
        End Get
    End Property

End Class

Public Class Cars2

    Inherits Xs(Of Car)

End Class

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

        Dim MyCar As New Car("key1", "prop1")

        'First approach
        Dim MyCars As New Cars

        MyCars.Add(MyCar)

        Dim RetrievedCar As Car = MyCars.Item("key1") 'Inefficient retrieval by key (uses looping)

        'Second approach
        Dim Cars2 As New Cars2

        Cars2.Add(MyCar)

        Dim RetrievedCar2 As Car = Cars2.Item("key1") 'Can now efficiently retreive an item by its key

End Sub

答案 3 :(得分:0)

如果您需要,可以通过索引和按键访问System.Collections.Specialized命名空间中的OrderedDictionary。但是看看你的解决方案,它看起来像一个标准的字典,但效率较低,因为它强制键的字符串类型。

有什么理由你不能使用Dictionary .NET提供给你的,或者像在OrderedDictionary中那样已经在.NET中的其他集合类型?