ArrayList vs List<> in C#

Viewed 448704

What is the difference between ArrayList and List<> in C#?

Is it only that List<> has a type while ArrayList doesn't?

12 Answers

Yes, pretty much. List<T> is a generic class. It supports storing values of a specific type without casting to or from object (which would have incurred boxing/unboxing overhead when T is a value type in the ArrayList case). ArrayList simply stores object references. As a generic collection, List<T> implements the generic IEnumerable<T> interface and can be used easily in LINQ (without requiring any Cast or OfType call).

ArrayList belongs to the days that C# didn't have generics. It's deprecated in favor of List<T>. You shouldn't use ArrayList in new code that targets .NET >= 2.0 unless you have to interface with an old API that uses it.

Simple Answer is,

ArrayList is Non-Generic

  • It is an Object Type, so you can store any data type into it.
  • You can store any values (value type or reference type) such string, int, employee and object in the ArrayList. (Note and)
  • Boxing and Unboxing will happen.
  • Not type safe.
  • It is older.

List is Generic

  • It is a Type of Type, so you can specify the T on run-time.
  • You can store an only value of Type T (string or int or employee or object) based on the declaration. (Note or)
  • Boxing and Unboxing will not happen.
  • Type safe.
  • It is newer.

Example:

ArrayList arrayList = new ArrayList();
List<int> list = new List<int>();

arrayList.Add(1);
arrayList.Add("String");
arrayList.Add(new object());


list.Add(1);
list.Add("String");                 // Compile-time Error
list.Add(new object());             // Compile-time Error

Please read the Microsoft official document: https://blogs.msdn.microsoft.com/kcwalina/2005/09/23/system-collections-vs-system-collection-generic-and-system-collections-objectmodel/

enter image description here

Note: You should know Generics before understanding the difference: https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/generics/

Performance has already been mentioned in several answers as a differentiating factor, but to address the “How much slower is the ArrayList ?” and “Why is it slower overall ?”, have a look below.

Whenever value types are used as elements, performance drops dramatically with ArrayList. Consider the case of simply adding elements. Due to the boxing going on - as ArrayList’s Add only takes object parameters - the Garbage Collector gets triggered into performing a lot more work than with List<T>.

How much is the time difference ? At least several times slower than with List<T>. Just take a look at what happens with code adding 10 mil int values to an ArrayList vs List<T>: enter image description here

That’s a run time difference of 5x in the ‘Mean’ column, highlighted in yellow. Note also the difference in the number of garbage collections done for each, highlighted in red (no of GCs / 1000 runs).

Using a profiler to see what’s going on quickly shows that most of the time is spent doing GCs, as opposed to actually adding elements. The brown bars below represent blocking Garbage Collector activity: enter image description here

I’ve written a detailed analysis of what goes on with the above ArrayList scenario here https://mihai-albert.com/2019/12/15/boxing-performance-in-c-analysis-and-benchmark/.

Similar findings are in “CLR via C#” by Jeffrey Richter. From chapter 12 (Generics):

[…] When I compile and run a release build (with optimizations turned on) of this program on my computer, I get the following output.

00:00:01.6246959 (GCs= 6) List<Int32>
00:00:10.8555008 (GCs=390) ArrayList of Int32
00:00:02.5427847 (GCs= 4) List<String>
00:00:02.7944831 (GCs= 7) ArrayList of String

The output here shows that using the generic List algorithm with the Int32 type is much faster than using the non-generic ArrayList algorithm with Int32. In fact, the difference is phenomenal: 1.6 seconds versus almost 11 seconds. That’s ~7 times faster! In addition, using a value type (Int32) with ArrayList causes a lot of boxing operations to occur, which results in 390 garbage collections. Meanwhile, the List algorithm required 6 garbage collections.

As mentioned in .NET Framework documentation

We don't recommend that you use the ArrayList class for new development. Instead, we recommend that you use the generic List<T> class. The ArrayList class is designed to hold heterogeneous collections of objects. However, it does not always offer the best performance. Instead, we recommend the following:

  • For a heterogeneous collection of objects, use the List<Object> (in C#) or List(Of Object) (in Visual Basic) type.
  • For a homogeneous collection of objects, use the List<T> class.

See also Non-generic collections shouldn't be used

table shows how the non-generic collection types can be replaced by their generic counterparts

Related