Framework Collections and Visual Basic Collections
The techniques to use Collections in Visual Basic programs have been documented in several articles at About Visual Basic such as Collections of Things (Part 10 of the Visual Basic .NET 2010 Express "From the Ground Up" Tutorial). A specific .NET Framework collection, generic List(Of T), is detailed specifically in the article, The Useful Generic List in VB.NET. But these articles don't mention one fact about collections that can occasionally give you trouble: Framework collections and Microsoft.VisualBasic collections are actually different things.
This article explains the difference and shows you an example of the Find method to illustrate the difference.
If you create a collection object in VB.NET like this:
You get a Microsoft.VisualBasic collection.
On the other hand, if you create a List(Of T) collection like this:
You get a System.Collections.Generic collection.
They're not the same thing. You can create a collection of the controls on a Windows form (a .NET Framework collection) using this code:
But this code won't compile because the compiler can't convert one type of collection into the other.
Ordinarily, this doesn't cause a problem. But occasionally, you have to write a little extra code. For example, in a recent project I wrote, I declared a generic List of CheckBox controls and paired them with an array of objects created in my program to track additional information for each CheckBox:
Working with one of the controls is easy. You can simply use the name of the control as a String key value. (In this example, a series CheckBox controls have all been placed inside a Panel container control for efficiency and each has a number assigned to the Tag property to identify it.)
If you want to do the same thing with a Microsoft.VisualBasic collection object, you have to be sure to Add each element with a key value before accessing it. The default is to assume an index value instead of a key.
If you're using a List(Of T) or an Array object, an alternative is to use a Find method to locate a specific element in the collection.
The use of a predicate delegate can be confusing if you're not used to using it. There are a number of methods that work this way with the Array object and collections such as Sort, FindAll and RemoveAll. One reason is probably that the choice of the words "predicate" and "delegate" is kind of obscure. Rather than "predicate", Microsoft probably should have used something like "procedureAddress" and "delegate" might have been "functionPointer".
You have probably used exactly the same kind of processing in your programming before. The idea is very similar to the code you would write to use a For Each block. The main difference is that the compiler writes the code. Each element in your collection or array is passed to a Function one at a time. The Function can have any code you like to select the records. For example, you could sort the elements and leave out any elements that start with a specific character. The example below is more simple; it just compares the tbID property in each element to the value in the variable myStringKey and returns that element.
You can check the elements of the collection for just about any condition this way and return the right element.
This article explains the difference and shows you an example of the Find method to illustrate the difference.
If you create a collection object in VB.NET like this:
Dim myCollection As New Collection
You get a Microsoft.VisualBasic collection.
On the other hand, if you create a List(Of T) collection like this:
Dim myList As New List(Of Control)
You get a System.Collections.Generic collection.
They're not the same thing. You can create a collection of the controls on a Windows form (a .NET Framework collection) using this code:
Dim myControls As New ControlCollection(Me)myControls = Me.Controls()For Each cntrl In myControlsConsole.WriteLine(cntrl.name)Next
But this code won't compile because the compiler can't convert one type of collection into the other.
' Incorrect CodeDim myControls As New CollectionmyControls = Me.Controls()
Ordinarily, this doesn't cause a problem. But occasionally, you have to write a little extra code. For example, in a recent project I wrote, I declared a generic List of CheckBox controls and paired them with an array of objects created in my program to track additional information for each CheckBox:
Public Class tbPublic Property tbVar1 As IntegerPublic Property tbVar2 As DateDim _tbID As IntegerPublic ReadOnly Property tbID As StringGettbID = _tbIDEnd GetEnd PropertyPublic Sub New(ByVal tbid As String)_tbID = tbidEnd SubEnd Class
Working with one of the controls is easy. You can simply use the name of the control as a String key value. (In this example, a series CheckBox controls have all been placed inside a Panel container control for efficiency and each has a number assigned to the Tag property to identify it.)
ControlPanel.Controls( "tbName" & tb.Tag).checked = False
If you want to do the same thing with a Microsoft.VisualBasic collection object, you have to be sure to Add each element with a key value before accessing it. The default is to assume an index value instead of a key.
myCollection.Add(tbObj, myStringKey)
If you're using a List(Of T) or an Array object, an alternative is to use a Find method to locate a specific element in the collection.
myStringKey = "the key value"mytb = myCollection.Find(AddressOf Findtb)
The use of a predicate delegate can be confusing if you're not used to using it. There are a number of methods that work this way with the Array object and collections such as Sort, FindAll and RemoveAll. One reason is probably that the choice of the words "predicate" and "delegate" is kind of obscure. Rather than "predicate", Microsoft probably should have used something like "procedureAddress" and "delegate" might have been "functionPointer".
You have probably used exactly the same kind of processing in your programming before. The idea is very similar to the code you would write to use a For Each block. The main difference is that the compiler writes the code. Each element in your collection or array is passed to a Function one at a time. The Function can have any code you like to select the records. For example, you could sort the elements and leave out any elements that start with a specific character. The example below is more simple; it just compares the tbID property in each element to the value in the variable myStringKey and returns that element.
' predicate delegate for Find methodPrivate Function Findtb(ByVal theTt As tb) As BooleanIf theTt.tbID = myStringKey ThenReturn TrueElseReturn FalseEnd IfEnd Function
You can check the elements of the collection for just about any condition this way and return the right element.
Source...