TL;DR
ArrayList
is an obsolete non-generic collection from pre-2005 .NET that stores everything asobject
- Using
ArrayList
causes performance issues due to boxing/unboxing of value types ArrayList
lacks compile-time type safety, leading to runtime exceptionsList<T>
and other generic collections offer superior performance, type safety, and developer experience- Boxing/unboxing with
ArrayList
can make code up to 10x slower in computation-heavy scenarios - Modern C# code should always use strongly-typed collections like
List<T>
,Dictionary<TKey,TValue>
, etc. - Even when storing mixed types, prefer
List<object>
overArrayList
for consistency
If you’re still using ArrayList
in your C# projects, you’re basically driving a horse-drawn carriage on a highway. Sure, it’ll get you there, but everyone’s zooming past you with better tools. Here’s why ArrayList
belongs in the .NET history books and what you should use instead.
What is ArrayList and Why Did It Exist?
Back when .NET was new (before 2005), we didn’t have generics. ArrayList
was the standard way to create dynamic collections for mixed types. It lives in the System.Collections
namespace and can hold any object, strings, integers, custom classes, whatever you need.
// The old way - ArrayList can hold anything
ArrayList oldList = new ArrayList();
oldList.Add("Hello");
oldList.Add(42);
oldList.Add(new DateTime(2024, 1, 1));
// This compiles fine, but creates problems later
The Modern Alternative: List
When generics arrived in .NET 2.0, List<T>
changed everything. Instead of storing everything as object
, you specify exactly what type you want to store.
// The modern way - type-safe and performant
List<string> modernList = new List<string>();
modernList.Add("Hello");
// modernList.Add(42); // Compile error - can't add int to List<string>
Why ArrayList Hurts Your Code
1. Boxing and Unboxing Performance Hit
Every time you add a value type to an ArrayList
, .NET boxes it into an object. When you retrieve it, you need to unbox it. This creates extra work for garbage collection and tanks your performance.
// ArrayList boxes integers - expensive!
ArrayList numbers = new ArrayList();
numbers.Add(1); // Boxing happens here
int first = (int)numbers[0]; // Unboxing and casting required
// List<T> stores values directly - fast!
List<int> betterNumbers = new List<int>();
betterNumbers.Add(1); // No boxing
int first = betterNumbers[0]; // Direct access, no casting
2. Runtime Errors from Type Confusion
ArrayList
compiles successfully but can explode at runtime when you cast to the wrong type.
ArrayList mixed = new ArrayList();
mixed.Add("text");
mixed.Add(123);
// This compiles but crashes at runtime
string text = (string)mixed[1]; // InvalidCastException!
3. No IntelliSense Love
Since ArrayList
returns object
, you lose all type information and IntelliSense support.
ArrayList vs List: The Comparison
Feature | ArrayList | List |
---|---|---|
Type Safety | Runtime only | Compile-time |
Performance | Boxing/unboxing overhead | Direct storage |
IntelliSense | Limited (returns object) | Full type support |
Casting Required | Always | Never |
Memory Usage | Higher (boxing) | Lower |
Runtime Errors | Common | Rare |
See here the detailed comparison of ArrayList
and List<T>
.
Common Pitfalls I’ve Seen
I’ve fixed so many bugs where developers mixed types in ArrayList
and got crashes when casting at runtime. The worst part? These bugs sneak into production because they compile without errors.
Another problem: loops get super slow when boxing/unboxing happens thousands of times. I once worked on a data processing app that ran 10x slower just because it used ArrayList
for number crunching.
The Bottom Line
Using ArrayList
in modern C# is like watching VHS tapes in a streaming world. The old tech still works, but you’re missing out on huge improvements in safety, speed, and coding experience.
Don’t use ArrayList
in modern C#. Go with List<T>
, IEnumerable<T>
, or other generic collections instead. Your future self (and your teammates) will thank you for writing code that’s type-safe, fast, and clearly shows what it does.
Generics changed C# for a reason, use them.
Related Posts
- SortedList vs SortedDictionary vs Lookup in C#: Differences & Use Cases
- Dictionary vs Hashtable in C#: Key Differences, Benchmarks & When to Use Each
- IEquatable<T> in C#: Why Every .NET Developer Should Master Custom Equality
- C# Default Interface Methods: Future-Proof and Backward-Compatible APIs
- Top 10 C# Collections Explained with Use Cases and Performance Impact