Say you’re taking RSVPs for an Austin C# meetup on March 12, 2026, and nobody knows if 4 or 40 people will sign up. A plain array can’t help, because its size is fixed the moment you create it.
A dynamic array in C# is a List<T>: it wraps an array and swaps in a bigger one whenever it fills up. We’ll build that RSVP list with a wait list on .NET 10, one step at a time. Here’s what we’re building:

Before You Start Building the Dynamic Array
You need the .NET 10 SDK and VS Code; every step is one file you run with dotnet run File.cs. If the square-bracket array syntax is new to you, skim my C# arrays guide first. Your sample data is one RSVP list:
| Attendee | Role in the build |
|---|---|
| Jenna Morales, Marcus Reed, Olivia Chen | Early sign-ups |
| Tyler Brooks | Cancels |
| Dana Whitfield | Speaker, inserted first |
| Ethan Parker, Hannah Lee | Late sign-ups |
Why Can’t a C# Array Grow? (Array.Resize Explained)
An array gets its length once, and writing past the end throws. Array.Resize is the old workaround:
string[] seats = ["Jenna Morales", "Tyler Brooks", "Marcus Reed"];
string[] before = seats;
try { seats[3] = "Olivia Chen"; }
catch (IndexOutOfRangeException ex) { Console.WriteLine(ex.Message); }
Array.Resize(ref seats, seats.Length + 1); // new array, items copied
seats[3] = "Olivia Chen";
Console.WriteLine($"Length now: {seats.Length}");
Console.WriteLine($"Same array as before? {ReferenceEquals(seats, before)}");
Console.WriteLine($"Old array length: {before.Length}");
Output:
Index was outside the bounds of the array.
Length now: 4
Same array as before? False
Old array length: 3
It doesn’t stretch anything: it allocates a new array, copies the items and repoints your ref variable, so before still has 3 slots. Doing that on every add is slow, so I hand the job to a list.
Step 1: Create the RSVP List and Watch Count vs Capacity
Add nine sign-ups to an empty List<string>. Count is items you have; Capacity is slots in the hidden array:
List<string> rsvps = new();
Console.WriteLine($"Start: Capacity {rsvps.Capacity}");
string[] names = ["Jenna Morales", "Tyler Brooks",
"Marcus Reed", "Olivia Chen", "Ethan Parker",
"Hannah Lee", "Caleb Ward", "Sofia Ramirez",
"Noah Bennett"];
foreach (string name in names)
{
rsvps.Add(name);
int count = rsvps.Count, cap = rsvps.Capacity;
Console.WriteLine($"Count {count}, Capacity {cap}");
}
Output:
Start: Capacity 0
Count 1, Capacity 4
Count 2, Capacity 4
Count 3, Capacity 4
Count 4, Capacity 4
Count 5, Capacity 8
Count 6, Capacity 8
Count 7, Capacity 8
Count 8, Capacity 8
Count 9, Capacity 16

In my run, Capacity went 0, 4, 8, 16. Each jump is a resize-and-copy List<T> does for you, and because it doubles, adds stay cheap on average.
Pro Tip: know the rough size? new List<string>(50) skips the early copies (more in my List in C# tutorial).
Checkpoint: the last line ends with Count 9, Capacity 16.
Step 2: Insert and Remove Attendees from the Dynamic Array
A speaker goes to the front, two people cancel and two late sign-ups arrive:
List<string> rsvps = ["Jenna Morales", "Tyler Brooks",
"Marcus Reed", "Olivia Chen"];
rsvps.Insert(0, "Dana Whitfield"); // speaker first
rsvps.Remove("Tyler Brooks"); // canceled, by name
rsvps.RemoveAt(rsvps.Count - 1); // canceled, by index
rsvps.AddRange(["Ethan Parker", "Hannah Lee"]);
Console.WriteLine(string.Join(", ", rsvps));
bool removed = rsvps.Remove("Zoe Hart");
Console.WriteLine($"Remove a missing name: {removed}");
Console.WriteLine($"Count: {rsvps.Count}");
Output:
Dana Whitfield, Jenna Morales, Marcus Reed, Ethan Parker, Hannah Lee
Remove a missing name: False
Count: 5

Insert shifts everyone right. Remove deletes the first match and returns false when there isn’t one; RemoveAt works by index.
Checkpoint: the first line starts with Dana Whitfield, Jenna Morales.
Step 3: Search the List with Contains, IndexOf and Find
At the door, you’ll look people up:
List<string> rsvps = ["Dana Whitfield", "Jenna Morales",
"Marcus Reed", "Ethan Parker", "Hannah Lee"];
var noCase = StringComparer.OrdinalIgnoreCase;
Console.WriteLine(rsvps.Contains("Marcus Reed"));
Console.WriteLine(rsvps.Contains("marcus reed"));
Console.WriteLine(rsvps.Contains("marcus reed", noCase));
Console.WriteLine(rsvps.IndexOf("Ethan Parker"));
Console.WriteLine(rsvps.IndexOf("Zoe Hart"));
Console.WriteLine(rsvps.Find(n => n.StartsWith('H')));
Output:
True
False
True
3
-1
Hannah Lee

Contains is case-sensitive, so pass StringComparer.OrdinalIgnoreCase (the LINQ overload) for typed input. IndexOf returns -1 and Find returns null on no match.
Arrays work similarly; see how to check if a string array contains an element.
Checkpoint: the lines read True, False, True, 3, -1 and Hannah Lee.
Step 4: Loop Through and Sort the List
Print the door list A-Z, then by last name:
List<string> rsvps = ["Marcus Reed", "Dana Whitfield",
"Jenna Morales", "Hannah Lee", "Ethan Parker"];
rsvps.Sort(StringComparer.Ordinal); // A-Z, in place
for (int i = 0; i < rsvps.Count; i++)
Console.WriteLine($"{i + 1}. {rsvps[i]}");
// by last name
rsvps.Sort((x, y) => string.CompareOrdinal(
x.Split(' ')[1], y.Split(' ')[1]));
Console.Write("By last name:");
foreach (string name in rsvps)
Console.Write($" {name.Split(' ')[1]}");
Console.WriteLine();
Output:
1. Dana Whitfield
2. Ethan Parker
3. Hannah Lee
4. Jenna Morales
5. Marcus Reed
By last name: Lee Morales Parker Reed Whitfield

Loop to Count, not Length. Sort changes the list itself and takes the same comparers as arrays; my guide to sort an array in C# covers descending and object sorts.
Checkpoint: the last line reads By last name: Lee Morales Parker Reed Whitfield.
Step 5: Convert the List to an Array with ToArray and [..]
The badge printer wants a fixed array, and you want guests plus the wait list in one list:
List<string> guests = ["Dana Whitfield", "Ethan Parker",
"Hannah Lee"];
string[] waitList = ["Caleb Ward", "Sofia Ramirez"];
string[] badges = guests.ToArray(); // fixed copy
// collection expression + spread (C# 12+)
List<string> all = [.. guests, .. waitList, "Walk-in"];
guests.Add("Noah Bennett");
Console.WriteLine($"List: {guests.Count}");
Console.WriteLine($"Array: {badges.Length}");
Console.WriteLine(string.Join(", ", all));
Output:
List: 4
Array: 3
Dana Whitfield, Ethan Parker, Hannah Lee, Caleb Ward, Sofia Ramirez, Walk-in

ToArray() is a copy, so adding Noah later doesn’t touch badges. The [.. guests, .. waitList] collection expression (spread element) needs C# 12 or later.
Checkpoint: List: 4 and Array: 3.
Test the Finished RSVP Dynamic Array
Here’s the program from the top. A foreach loop in C# fills four seats and wait-lists the rest; when Tyler cancels, the first wait-listed guest moves up:
const int Seats = 4;
List<string> rsvps = [], waitList = [];
string[] signups = ["Jenna Morales", "Tyler Brooks",
"Marcus Reed", "Olivia Chen",
"Ethan Parker", "Hannah Lee"];
foreach (string name in signups)
(rsvps.Count < Seats ? rsvps : waitList).Add(name);
rsvps.Remove("Tyler Brooks"); // canceled
rsvps.Add(waitList[0]); // wait list moves up
waitList.RemoveAt(0);
rsvps.Sort(StringComparer.Ordinal);
string seats = $"{rsvps.Count}/{Seats}";
Console.WriteLine($"Austin C# Meetup 3/12/2026 ({seats})");
for (int i = 0; i < rsvps.Count; i++)
Console.WriteLine($" {i + 1}. {rsvps[i]}");
Console.WriteLine($"Waiting: {waitList[0]}");
bool marcus = rsvps.Contains("Marcus Reed");
Console.WriteLine($"Marcus Reed seated? {marcus}");
Output:
Austin C# Meetup 3/12/2026 (4/4)
1. Ethan Parker
2. Jenna Morales
3. Marcus Reed
4. Olivia Chen
Waiting: Hannah Lee
Marcus Reed seated? True
Ethan took Tyler’s seat and Hannah’s still waiting. Two lists, and no size declared anywhere.
Array vs List<T> vs ArrayList: Which Dynamic Array Should You Use?
string[] array | List<string> | ArrayList | |
|---|---|---|---|
| Size | Fixed | Grows and shrinks | Grows and shrinks |
| Type-safe | Yes | Yes | No, stores object |
| Value types | No boxing | No boxing | Boxed |
| Use it for | Known size, hot loops | Almost everything | Legacy code only |
ArrayList is the pre-generics dynamic array from .NET 1.0, and Microsoft recommends List<T> for new code. I explain the migration in my ArrayList in C# tutorial.
Troubleshooting Dynamic Array Errors in C#
The two mistakes I see most:
List<string> rsvps = ["Jenna Morales", "Tyler Brooks", "Marcus Reed"];
try { Console.WriteLine(rsvps[3]); }
catch (ArgumentOutOfRangeException ex) { Console.WriteLine(ex.GetType().Name); }
try { foreach (var n in rsvps) if (n.StartsWith('T')) rsvps.Remove(n); }
catch (InvalidOperationException ex) { Console.WriteLine(ex.Message); }
rsvps.RemoveAll(n => n.StartsWith('M')); // the safe way to remove while filtering
Console.WriteLine(string.Join(", ", rsvps));
Output:
ArgumentOutOfRangeException
Collection was modified; enumeration operation may not execute.
Jenna Morales
ArgumentOutOfRangeException: the index is >= Count. Spare Capacity isn’t readable.
Collection was modified: you can’t add or remove inside foreach. Use RemoveAll or walk a for loop in C# backwards.
Where to Take It Next
- Look up attendees by email instead of position with a Dictionary in C#.
- Export the final list for an email tool by turning it into a comma-separated string.
A few more array and collection tutorials you’ll find handy:
- How to reverse an array in C#
- Hashtable in C#, the other legacy collection
- Convert a char array to a string in C#
Frequently Asked Questions
Does C# have dynamic arrays?
Not as a separate type. Arrays are fixed-size; List<T> is the built-in dynamic array.
What’s the difference between Count and Capacity in a C# List?
Count is the number of items; Capacity is the size of the inner array. Microsoft’s List<T>.Capacity reference explains that the list reallocates and copies when Count exceeds Capacity.
Does Array.Resize change the original array?
No. It creates a new array and updates your ref variable; other references keep the old one.
Is List<T> slower than an array in C#?
Slightly, for reads in tight loops. When items come and go, it beats resizing an array yourself.
How do I convert a List to an array in C#?
Call list.ToArray(), or use the collection expression string[] arr = [.. list]; on C# 12 or later. Both make a copy.
Bijay Kumar is a renowned software engineer, accomplished author, and distinguished Microsoft Most Valuable Professional (MVP) specializing in SharePoint. With a rich professional background spanning over 15 years, Bijay has established himself as an authority in the field of information technology. He possesses unparalleled expertise in multiple programming languages and technologies such as ASP.NET, ASP.NET MVC, C#.NET, and SharePoint, which has enabled him to develop innovative and cutting-edge solutions for clients across the globe. Read more…