VB.NET List – Create, Sort, Filter with Examples (2026)
The VB.NET List is one of the most used data structures in .NET development. It stores objects in an ordered, resizable collection and gives you methods to add, remove, sort, and search items with minimal code. This guide covers everything from basic creation to LINQ queries and performance considerations.
Inhaltsverzeichnis
What is a List(Of T) and when to use it
A List(Of T) is a generic collection from the System.Collections.Generic namespace. The T stands for the type of objects you want to store: List(Of String) holds strings, List(Of Integer) holds numbers, List(Of Customer) holds your own objects.
Use a List when:
- You need an ordered collection where items have a position (index)
- The number of items changes at runtime (unlike arrays, which have a fixed size)
- You want built-in methods for sorting, searching, and filtering
- You access items by position, not by a key
If you need key-value lookups instead (e.g. finding a customer by ID), use a VB.NET Dictionary. Lists search by iterating through every item, which gets slow with large datasets. Dictionaries find entries in constant time.
Creating a List
The most common ways to create a List(Of T):
' Empty list
Dim names As New List(Of String)
' List with initial values
Dim numbers As New List(Of Integer) From {3, 5, 7, 9}
' List of custom objects
Dim customers As New List(Of Customer) From {
New Customer With {.Name = "Alice", .Email = "alice@example.com"},
New Customer With {.Name = "Bob", .Email = "bob@example.com"}
}
The From keyword together with curly braces is a collection initializer. It calls Add() for each item behind the scenes.
Setting an initial capacity
If you know roughly how many items the list will hold, set the capacity upfront. This avoids repeated internal array resizing:
' Pre-allocate space for ~500 items Dim largeList As New List(Of String)(500)
This doesn’t limit the list to 500 items. It just avoids unnecessary memory allocations until you exceed that number.
Adding items
Add and AddRange
Dim names As New List(Of String)
' Add single items
names.Add("Alice")
names.Add("Bob")
' Add multiple items at once
names.AddRange({"Clara", "David", "Eva"})
' Add items from another list
Dim moreNames As New List(Of String) From {"Frank", "Grace"}
names.AddRange(moreNames)
Insert at a specific position
' Insert "Zara" at position 0 (beginning) names.Insert(0, "Zara") ' Insert at position 2 names.Insert(2, "Maria")
Be aware that Insert() shifts all subsequent items, which costs O(n). For frequent insertions at the beginning, consider a LinkedList(Of T) instead.
Accessing items
Items are accessed by their zero-based index:
Dim names As New List(Of String) From {"Alice", "Bob", "Clara"}
' Access by index
Dim first As String = names(0) ' "Alice"
Dim last As String = names(names.Count - 1) ' "Clara"
' Iterate with For Each
For Each name In names
Console.WriteLine(name)
Next
' Iterate with index
For i As Integer = 0 To names.Count - 1
Console.WriteLine($"[{i}] {names(i)}")
Next
Accessing an invalid index throws an ArgumentOutOfRangeException. Always check Count before using a specific index, or use methods like FirstOrDefault() from LINQ.
Removing items
Dim names As New List(Of String) From {"Alice", "Bob", "Clara", "David"}
' Remove by value (first occurrence)
names.Remove("Bob") ' returns True if found
' Remove by index
names.RemoveAt(0) ' removes "Alice"
' Remove last item
If names.Count > 0 Then
names.RemoveAt(names.Count - 1)
End If
' Remove all items matching a condition
names.RemoveAll(Function(n) n.StartsWith("C"))
' Remove everything
names.Clear()
Remove() searches the list from the beginning and removes the first match. If the item doesn’t exist, it returns False without throwing an exception. RemoveAt() on an invalid index does throw.
Sorting a List
Simple sort
Dim names As New List(Of String) From {"Clara", "Alice", "Bob"}
' Sort alphabetically (in-place)
names.Sort()
' Result: Alice, Bob, Clara
' Reverse the order
names.Reverse()
' Result: Clara, Bob, Alice
Sort with custom comparison
For custom objects, pass a comparison lambda to Sort():
Public Class Contact
Public Property Name As String
Public Property Age As Integer
End Class
Dim contacts As New List(Of Contact) From {
New Contact With {.Name = "Clara", .Age = 30},
New Contact With {.Name = "Alice", .Age = 25},
New Contact With {.Name = "Bob", .Age = 35}
}
' Sort by name
contacts.Sort(Function(a, b) String.Compare(a.Name, b.Name))
' Sort by age (descending)
contacts.Sort(Function(a, b) b.Age.CompareTo(a.Age))
Sorting with LINQ (non-destructive)
Sort() modifies the original list. If you want a new sorted list without changing the original, use LINQ:
' Original stays unchanged Dim sorted = contacts.OrderBy(Function(c) c.Name).ToList() Dim sortedDesc = contacts.OrderByDescending(Function(c) c.Age).ToList()
Searching and filtering with LINQ
LINQ is the most powerful way to query lists in VB.NET. Import System.Linq (usually imported by default) and you get a full set of query methods:
Find items
Dim contacts As New List(Of Contact) From {
New Contact With {.Name = "Alice", .Age = 25},
New Contact With {.Name = "Bob", .Age = 35},
New Contact With {.Name = "Clara", .Age = 30}
}
' Find first match (returns Nothing if not found)
Dim alice = contacts.FirstOrDefault(Function(c) c.Name = "Alice")
' Check if any item matches
Dim hasOlderThan30 As Boolean = contacts.Any(Function(c) c.Age > 30)
' Check if all items match
Dim allAdults As Boolean = contacts.All(Function(c) c.Age >= 18)
Filter items
' Get all contacts older than 25
Dim olderContacts = contacts.Where(Function(c) c.Age > 25).ToList()
' Get just the names
Dim names = contacts.Select(Function(c) c.Name).ToList()
' Combine: filter + transform
Dim olderNames = contacts _
.Where(Function(c) c.Age > 25) _
.Select(Function(c) c.Name) _
.ToList()
Aggregate queries
' Count, Min, Max, Average, Sum Dim count As Integer = contacts.Count Dim youngest As Integer = contacts.Min(Function(c) c.Age) Dim oldest As Integer = contacts.Max(Function(c) c.Age) Dim averageAge As Double = contacts.Average(Function(c) c.Age) ' Distinct values Dim uniqueAges = contacts.Select(Function(c) c.Age).Distinct().ToList()
Converting lists
Lists can be converted to and from other collection types:
' List to Array
Dim namesArray As String() = names.ToArray()
' Array to List
Dim backToList As List(Of String) = namesArray.ToList()
' List to Dictionary (key must be unique)
Dim contactDict = contacts.ToDictionary(
Function(c) c.Name,
Function(c) c)
' String from List (join)
Dim csv As String = String.Join(", ", names)
' Result: "Alice, Bob, Clara"
The ToDictionary() conversion is especially useful when you later need fast lookups by key. Read more about that in the Dictionary guide.
List vs. Array vs. Dictionary
Choosing the right collection type matters for both readability and performance. Here’s a comparison of the most common choices:
| List(Of T) | Array | Dictionary(Of TKey, TValue) | |
|---|---|---|---|
| Size | Dynamic | Fixed | Dynamic |
| Access by index | O(1) | O(1) | N/A |
| Access by key | O(n) | O(n) | O(1) |
| Add item | O(1) amortized | N/A (fixed size) | O(1) amortized |
| Remove item | O(n) | N/A | O(1) |
| Best for | Ordered collections, iteration | Fixed-size buffers, interop | Key-value lookups |
A detailed performance comparison with real benchmarks is available in the C# List guide, which applies equally to VB.NET since both use the same .NET runtime.
Common pitfalls
Modifying a list during iteration
This is one of the most frequent beginner mistakes. Removing items inside a For Each loop throws an InvalidOperationException:
' BAD - throws InvalidOperationException!
For Each name In names
If name.StartsWith("A") Then
names.Remove(name)
End If
Next
' GOOD - use RemoveAll instead
names.RemoveAll(Function(n) n.StartsWith("A"))
' ALSO GOOD - iterate backwards with For
For i As Integer = names.Count - 1 To 0 Step -1
If names(i).StartsWith("A") Then
names.RemoveAt(i)
End If
Next
Using a List for lookups
If you frequently search for items by a unique property (name, ID, email), a List is the wrong choice. Every search iterates the entire list. A Dictionary finds the item instantly. This difference becomes massive with thousands of entries, as demonstrated in this benchmark comparison.
Forgetting to call ToList()
LINQ methods like Where() and Select() return lazy IEnumerable objects, not lists. Each time you iterate, the query runs again. Call .ToList() to materialize the result:
' Lazy - runs the filter twice! Dim filtered = names.Where(Function(n) n.Length > 3) Console.WriteLine(filtered.Count()) ' filter runs here Console.WriteLine(filtered.Count()) ' filter runs again ' Better - materialize once Dim filteredList = names.Where(Function(n) n.Length > 3).ToList() Console.WriteLine(filteredList.Count) ' just reads the count Console.WriteLine(filteredList.Count) ' same, no re-evaluation
FAQ
Use Dim myList As New List(Of String) for an empty list, or Dim myList As New List(Of String) From {"Alice", "Bob"} with initial values. Replace String with whatever type you need.
Arrays have a fixed size set at creation. Lists grow and shrink dynamically with Add() and Remove() methods. Use arrays for fixed-size buffers, use lists whenever the number of items can change.
Call myList.Sort() for default sorting. For custom objects, use a lambda: myList.Sort(Function(a, b) a.Name.CompareTo(b.Name)). Use LINQ OrderBy() if you want a new list without modifying the original.
Use Remove(item) to remove by value, RemoveAt(index) by position, or RemoveAll(Function(x) condition) to remove all matching items. Never remove items inside a For Each loop.
Use a Dictionary whenever you need to look up items by a unique key (name, ID, email). A List needs to iterate every entry to find a match (O(n)), while a Dictionary does it in constant time (O(1)).
Wrapping up
The List(Of T) is the go-to collection for ordered, resizable data in VB.NET. Use Add() and RemoveAll() for basic operations, Sort() with a lambda for custom sorting, and LINQ for filtering and transforming. For key-based lookups, switch to a Dictionary. If you’re working with C# as well, the same concepts apply with slightly different syntax, as shown in the C# List guide.