title: Converting VB6 Collections to VB.Net generics
body: <p>All,</p>
  
  <p>I have a VB6 project with about 100 custom collection classes which I want to convert to VB.Net. A typical example would be something like.</p>
  
  <pre><code>Class CAccounts
       Private m_Accounts As New Collection
  
       Public Sub Add(newItem As CAccount)
           m_Accounts.Add newItem, newItem.IdKey
       End Sub
       Public Sub Remove(index As Variant)
           m_Accounts.Remove index
       End Sub
       Public Function Item(index As Variant) As CAccount
           Set Item = Nothing
           On Error Resume Next
           Set Item = m_Accounts.Item(index)
       End Function
  
       .........
  </code></pre>
  
  <p>Where the item being stored is  </p>
  
  <pre><code>Class CAccount
      Public Id as long
      Public Code as String
      Public Name as string
      Public Sub Init(ByVal Id as Long)
          Me.Id = Id
          Code = ""
          Name = ""
      End Sub
      Public Property Get IdKey() as String
          IdKey = Code
      End Property
  
      ......
  </code></pre>
  
  <p>All of the collection classes in the project use this standard approach. However, not all the properties/methods of the collection classes are actually used. Most of the collection are used in "for each" loops. Keyed access using the string key is quite common. Keyed access by index is much less common.</p>
  
  <p>Ideally I'd like to take a standard approach to converting these classes. I don't really want to have to review each collection and it's usage to consider whether I need a List, Dictionary, etc. Some of these collection contain 100,000 objects, and some will only contain 10.  However, on the other hand I don't want to cause performance problems by using a more complex structure where a simpler option would do.</p>
  
  <p>I'd appreciate any advice on the best approach. I've considered the following.</p>
  
  <ol>
  <li><p>Sticking with the old style Collection. So, it would be relatively easy to convert to VB.Net But, I'd rather move to the more modern structures.</p></li>
  <li><p>Have CAccounts Inherit KeyedCollection(Of String, CAccount). Fortunately most of the classes held in the collections do have the key as part of the class (eg CAccount.IdKey above). This seems to work well. However, relatively few classes will access the colelction by numeric index. So, perhaps this is overkill if I only want keyed access by the string key?</p></li>
  <li><p>Have CAccounts Inherit Dictionary(Of String, CAccount) for the classes where I don't need access by numeric index. The problem I have with this is that all the existing "for each" loops are like "for each account in accounts". I don't want to have to change all these occurences to something like "for each account in accounts.Values". Although perhaps I can get round this by changing the default property?</p></li>
  <li><p>Have CAccounts Inherit MyCollection(Of String, CAccount), where MyCollection is my own bespoke collection. This seems a bit too much hard work.</p></li>
  </ol>
  
  <p>I'm inclined to go for option 2 - make everything a KeyedCollection. Then make exceptions if required (eg non-unique keys). However, if KeyedCollections are much slower than Dictionarys I might go for Dictionary as the standard, and just use KeyedCollection where I need access by numeric index.</p>
  
  <p>All advice appreciated.</p>