Array versus List<T>: When to use which?

Viewed 378618
MyClass[] array;
List<MyClass> list;

What are the scenarios when one is preferable over the other? And why?

16 Answers

It is rare, in reality, that you would want to use an array. Definitely use a List<T> any time you want to add/remove data, since resizing arrays is expensive. If you know the data is fixed length, and you want to micro-optimise for some very specific reason (after benchmarking), then an array may be useful.

List<T> offers a lot more functionality than an array (although LINQ evens it up a bit), and is almost always the right choice. Except for params arguments, of course. ;-p

As a counter - List<T> is one-dimensional; where-as you have have rectangular (etc) arrays like int[,] or string[,,] - but there are other ways of modelling such data (if you need) in an object model.

See also:

That said, I make a lot of use of arrays in my protobuf-net project; entirely for performance:

  • it does a lot of bit-shifting, so a byte[] is pretty much essential for encoding;
  • I use a local rolling byte[] buffer which I fill before sending down to the underlying stream (and v.v.); quicker than BufferedStream etc;
  • it internally uses an array-based model of objects (Foo[] rather than List<Foo>), since the size is fixed once built, and needs to be very fast.

But this is definitely an exception; for general line-of-business processing, a List<T> wins every time.

Really just answering to add a link which I'm surprised hasn't been mentioned yet: Eric's Lippert's blog entry on "Arrays considered somewhat harmful."

You can judge from the title that it's suggesting using collections wherever practical - but as Marc rightly points out, there are plenty of places where an array really is the only practical solution.

Notwithstanding the other answers recommending List<T>, you'll want to use arrays when handling:

  • image bitmap data
  • other low-level data-structures (i.e. network protocols)

Unless you are really concerned with performance, and by that I mean, "Why are you using .Net instead of C++?" you should stick with List<>. It's easier to maintain and does all the dirty work of resizing an array behind the scenes for you. (If necessary, List<> is pretty smart about choosing array sizes so it doesn't need to usually.)

If I know exactly how many elements I'm going to need, say I need 5 elements and only ever 5 elements then I use an array. Otherwise I just use a List<T>.

Arrays Vs. Lists is a classic maintainability vs. performance problem. The rule of thumb that nearly all developers follow is that you should shoot for both, but when they come in to conflict, choose maintainability over performance. The exception to that rule is when performance has already proven to be an issue. If you carry this principle in to Arrays Vs. Lists, then what you get is this:

Use strongly typed lists until you hit performance problems. If you hit a performance problem, make a decision as to whether dropping out to arrays will benefit your solution with performance more than it will be a detriment to your solution in terms of maintenance.

Populating a list is easier than an array. For arrays, you need to know the exact length of data, but for lists, data size can be any. And, you can convert a list into an array.

List<URLDTO> urls = new List<URLDTO>();

urls.Add(new URLDTO() {
    key = "wiki",
    url = "https://...",
});

urls.Add(new URLDTO()
{
    key = "url",
    url = "http://...",
});

urls.Add(new URLDTO()
{
    key = "dir",
    url = "https://...",
});

// convert a list into an array: URLDTO[]
return urls.ToArray();

Keep in mind that with List is not possible to do this:

List<string> arr = new List<string>();

arr.Add("string a");
arr.Add("string b");
arr.Add("string c");
arr.Add("string d");

arr[10] = "new string";

It generates an Exception.

Instead with arrays:

string[] strArr = new string[20];

strArr[0] = "string a";
strArr[1] = "string b";
strArr[2] = "string c";
strArr[3] = "string d";

strArr[10] = "new string";

But with Arrays there is not an automatic data structure resizing. You have to manage it manually or with Array.Resize method.

A trick could be initialize a List with an empty array.

List<string> arr = new List<string>(new string[100]);

arr[10] = "new string";

But in this case if you put a new element using Add method it will be injected in the end of the List.

List<string> arr = new List<string>(new string[100]);

arr[10] = "new string";

arr.Add("bla bla bla"); // this will be in the end of List

It completely depends on the contexts in which the data structure is needed. For example, if you are creating items to be used by other functions or services using List is the perfect way to accomplish it.

Now if you have a list of items and you just want to display them, say on a web page array is the container you need to use.

Related