2009-04-28 65 views
0

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

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

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

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

这就是我想要做的,除了用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

我相信你正在寻找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 
0

你真的需要通过键和索引访问?

如果你不这样做,然后用一个词典(串,汽车),并使用 - MyCol.Items("XXX")来检索键(简写MyCol(“XXX”)或) 项目 - MyCol.ContainsKey("XXX")如果一键测试 存在集合中 - For Each Entry as KeyValuePair(Of String, Car)在MyCol如果要列举所有对象及其关键 - 每个条目中MyCol.Values车,如果你想搜索的条目,而不考虑的关键

如果同时需要访问索引和关键,恐怕你最好的选择是使用列表(汽车)和字典(汽车)卷入一个自定义集合类,因为我相信他们离开了那个k对于大多数问题来说,收集并不是很有用。

+0

是的,它看起来像字典对象会做得很好。我想我没有意识到它内部的元素可以键入 – ChadD 2009-05-02 21:19:37

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 
+0

现在,您正在创建自己的非通用字典,当字典中已经存在一个字典时。为什么? – 2009-04-28 19:06:10

0

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

是否有任何理由,你不能使用字典.NET提供给你,或另一种已经在.NET中的集合类型像OrderedDictionary?