100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
Programming

Collections and Generics in VB.NET

Move beyond fixed arrays to type-safe, resizable generic collections like List(Of T) and Dictionary(Of TKey, TValue), and write your own generic methods.

OOP in VB.NETIntermediate10 min readJul 10, 2026
Analogies

From Arrays to Collections

A traditional VB.NET array like Dim scores(9) As Integer has a fixed size set at creation and must be redimensioned with ReDim Preserve to grow, which is clumsy for data whose size isn't known in advance. The System.Collections.Generic namespace provides dynamically resizable collection types such as List(Of T), Dictionary(Of TKey, TValue), and Queue(Of T) that handle growth internally while still enforcing compile-time type safety through generics.

🏏

Cricket analogy: A fixed 11-seat team bus that can't add a 12th player without physically welding on an extra seat is like a fixed-size array, whereas a modern squad management system that flexibly rosters 15, 18, or 20 players as needed mirrors a resizable List(Of T).

Generic List(Of T) and Type Safety

Declaring Dim names As New List(Of String) restricts the collection to holding only String values, so attempting to Add an Integer produces a compile-time error rather than a runtime surprise -- this is the core benefit generics provide over the older non-generic ArrayList, which stored everything as Object and required error-prone casting on retrieval.

🏏

Cricket analogy: A dedicated kit bag labeled 'bats only' that physically rejects a stray cricket ball being placed inside mirrors List(Of Bat) rejecting a non-Bat item at compile time, unlike an old generic equipment box where anything could be tossed in and mixed up.

vbnet
Dim scores As New List(Of Integer)
scores.Add(85)
scores.Add(92)
scores.Add(78)
' scores.Add("high")   ' Compile-time error: String cannot convert to Integer

For Each s As Integer In scores
    Console.WriteLine(s)
Next

Dim playerScores As New Dictionary(Of String, Integer) From {
    {"Alice", 95},
    {"Bilal", 88}
}

Dim result As Integer
If playerScores.TryGetValue("Alice", result) Then
    Console.WriteLine("Alice scored " & result)
End If

Dictionary(Of TKey, TValue) for Key-Based Lookup

A Dictionary(Of TKey, TValue) stores key-value pairs and provides near-instant lookup by key rather than the linear scan a List(Of T) requires to find an item -- calling playerScores("Alice") directly retrieves Alice's associated value without iterating through every entry, and attempting to read a missing key throws a KeyNotFoundException unless you first check ContainsKey or use TryGetValue.

🏏

Cricket analogy: A scorer's indexed player-stats card, where looking up 'Kohli' instantly returns his career average without scanning every player on the sheet, mirrors Dictionary(Of String, Double)'s instant key-based lookup versus a List's slower linear scan.

TryGetValue is generally preferred over checking ContainsKey and then using the indexer, because ContainsKey plus the indexer performs two separate lookups while TryGetValue performs a single lookup and never throws an exception if the key is missing.

Writing Your Own Generic Methods and Classes

Beyond using built-in generic collections, you can declare your own generic procedures and classes with Of T, such as Public Function FindMax(Of T As IComparable)(items As List(Of T)) As T, where the As IComparable constraint guarantees the compiler that any type substituted for T supports comparison. This lets a single method body work correctly across Integer, String, or any custom type implementing IComparable, without duplicating logic for each type.

🏏

Cricket analogy: A single universal FindTopScorer analysis tool that works whether you feed it ODI stats, T20 stats, or Test stats, as long as each format's data supports comparison, mirrors a generic FindMax(Of T As IComparable) working across types.

Omitting a constraint like As IComparable means you cannot call .CompareTo or other type-specific members on T inside the generic method -- the compiler only allows what's guaranteed by Object unless a constraint is specified. Other useful constraints include Of T As {New, Class} for types requiring a parameterless constructor and reference semantics.

  • Fixed-size arrays require ReDim Preserve to grow, which is clumsy for unpredictable data sizes.
  • List(Of T) dynamically resizes while enforcing compile-time type safety through its generic parameter.
  • Dictionary(Of TKey, TValue) provides near-instant key-based lookup instead of a linear scan.
  • TryGetValue avoids exceptions and redundant lookups compared to checking ContainsKey then indexing.
  • Generics let one method or class body work correctly across many types without duplicating logic.
  • Type constraints like Of T As IComparable guarantee the compiler that T supports needed operations.
  • Generic collections like List(Of T) and Dictionary(Of TKey, TValue) replace older non-generic, unsafe types like ArrayList.

Practice what you learned

Was this page helpful?

Topics covered

#Programming#VBNETStudyNotes#CollectionsAndGenericsInVBNET#Collections#Generics#NET#Arrays#StudyNotes#SkillVeris#ExamPrep