Arrays vs ArrayLists in C#: Which One Should You Pick?
If you’ve been coding in C# for a while, you’ve probably used both arrays and ArrayLists. Let’s break down the real differences between these two collection types and talk about when you might want to use each one.
The Basics: What’s the Difference?
An array in C# is pretty straightforward, it’s a fixed-size collection where all elements must be the same type. Once you create it, that’s it, the size is locked in.
An ArrayList, on the other hand, is much more flexible. It can grow or shrink as you add or remove items, and it doesn’t care what types you throw into it, mix and match to your heart’s content.
How They Stack Up Against Each Other
1. Size: Fixed vs Flexible
With arrays, you’re committed to a size upfront:
// You're stuck with 5 slots, no more, no less
string[] namesArray = new string[5];
ArrayLists are much more easy-going:
ArrayList namesList = new ArrayList();
namesList.Add("Alex"); // No problem, it just grows
namesList.Remove("Alex"); // Shrinks back down
2. Type Safety: Strong vs Loose
Arrays won’t let you mix types, which helps catch errors early:
string[] stringArray = new string[3];
stringArray[0] = "This works fine";
// stringArray[1] = 42; // Compiler stops you right here
ArrayLists are the wild west of types:
ArrayList mixedList = new ArrayList();
mixedList.Add("A string");
mixedList.Add(42); // Works fine, but can bite you later
3. Speed: Fast vs Convenient
Arrays are speed demons because:
- They use a simpler memory structure
- They don’t need type conversion gymnastics
- They never need to resize
ArrayLists are more convenient but come with some costs:
- They have to box/unbox value types
- They need to resize when they grow
- They make you cast when getting items out
See It in Action
Here’s a quick example showing how they behave differently:
using System;
using System.Collections;
class Program
{
static void Main()
{
Console.WriteLine("=== Array Example ===");
// Simple fruit array
string[] fruitArray = new string[] { "apple", "banana", "cherry" };
Console.WriteLine($"Array length: {fruitArray.Length}"); // Shows 3
// Change an apple to an apricot
fruitArray[0] = "apricot";
// Try adding another fruit? Nope!
// fruitArray[3] = "date"; // Crashes with IndexOutOfRangeException
Console.WriteLine("\n=== ArrayList Example ===");
// Same fruits in an ArrayList
ArrayList fruitList = new ArrayList { "apple", "banana", "cherry" };
Console.WriteLine($"ArrayList count: {fruitList.Count}"); // Shows 3
// Want to add more fruit? No problem
fruitList.Add("date");
Console.WriteLine($"After adding date: {fruitList.Count}"); // Now 4
// Mix in some non-fruit items
fruitList.Add(100); // A number in our fruit list? Sure!
fruitList.Add(null); // Even null values are welcome
Console.WriteLine($"After adding mixed items: {fruitList.Count}"); // Now 6
// Getting stuff out requires casting
string firstFruit = (string)fruitList[0];
Console.WriteLine($"First fruit: {firstFruit}");
// Be careful or you'll get exceptions
// int number = (int)fruitList[0]; // Boom! Can't turn a string into an int
}
}
When Should You Use Each One?
Grab an Array When:
- You know exactly how many items you need
- You want the fastest possible performance
- You want the compiler to catch type mistakes
- You’re working with numbers or other value types
Reach for an ArrayList When:
- Your collection needs to grow and shrink
- You need to mix different types in one collection
- You care more about flexibility than catching type issues early
- You’re stuck maintaining older code
What About Modern C#?
These days, most developers skip ArrayLists entirely and use the generic List<T>
instead. It gives you the best of both worlds, it’s flexible like ArrayList but type-safe like arrays:
// The modern way to do collections
List<string> fruitList = new List<string> { "apple", "banana", "cherry" };
fruitList.Add("date"); // Flexible sizing
// fruitList.Add(100); // But this won't work —> type safety!
Pick the right tool for your specific job. Need fixed size and speed? Array. Need flexibility with type safety? Go with List<T>
. And if you really need to mix types, ArrayList is still there, just be ready to handle those casting issues.