tags:

views:

1910

answers:

10
MyClass[] array;
List<MyClass> list;

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

+33  A: 

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.

Marc Gravell
The argument about resizing is totally valid. However people prefer Lists even when no resizing is needed. For this latter case, is there a solid, logical argument or is it nothing more than "arrays are out of fashion"?
Frederick
@Frederick: hard to answer without hearing the "why". Actually, in many cases I'd prefer `IList<T>` or `IEnumerable<T>` - it lets the caller decide what they want to use (`T[]` or `List<T>` etc). LINQ largely balances out a lot of the extra `List<T>` functions (over `IList<T>`).
Marc Gravell
Actually, I'm working with a legacy, C# 1.0 codebase. Some of the functions there take and return arrays. No resizing or anything is happening....
Frederick
...Now, in my wrapper functions, I'm inclined to use List<T>'s instead of arrays. But I have no solid reasoning to justify this. Just a warm fuzzy feeling. I need a good argument for my decision.
Frederick
Well, things are slightly different without generics... Boxing and casting aren't the *worst* things in the world, but it adds up. I'd say that arrays have a *bit* more place in .NET 1.x than now, but there is still ArrayList etc if you can live with the box/cast/no-compile-time-checking pain.
Marc Gravell
@Frederick - seriously: consider IList<T> (if you need add/remove/indexer) or IEnumerable<T> (if you just need `foreach`).
Marc Gravell
I don't fully understand this: does working with an array need boxing/unboxing? Even if the type contained in the array is a ref type? And is casting needed too? But isn't an array strongly typed? PS: I'm just curious if there's just some dogma against arrays. PPS: Yet to read Jon Skeet's link.
Frederick
Yeah. I appreciate and agree with using IList<T> and IEnumerable<T>. They make your class user less constrained in terms of what to supply to and expect back from your class.
Frederick
@Frederick - my boxing/cast comments were directed at ArrayList etc, since they are the closest option to List<T> in .NET 1.x
Marc Gravell
"Definitely use a List<T> any time you want to add/remove data, since resizing arrays is expensive." List<T> uses an array internally. Were you thinking of LinkedList<T>?
dangph
+2  A: 

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.)

Spencer Ruport
+1  A: 

Arrays are rather obsolete, as seen in a popular discussion here. Also pointed out here, and by our host in the blog.

gimel
A: 

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.

Syed Sajid Nizami
If you have a list of items and you just want to display them, then what is wrong with just using the list you already have? What would an array offer here?
Marc Gravell
And for "creating items to be used by other functions or services", actually, I'd prefer an iterator block with `IEnumerable<T>` - then I can stream objects rather than buffer them.
Marc Gravell
A: 

Agree with Marc + for interoperability you can't have List<> as argument of a method

pablito
+3  A: 

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)
Alnitak
Why for network protocols? Wouldn't you rather use custom structures here and give them an special serializer or an explicit memory layout? Furthermore, what speaks against using a `List<T>` here rather than a byte array?
Konrad Rudolph
@Konrad - well, for starters, Stream.Read and Stream.Write work with byte[], as does Encoding etc...
Marc Gravell
+12  A: 

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.

Jon Skeet
A: 

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>.

smack0007
+2  A: 

Use an array when you are dealing with data that is:

  • fixed in size, or unlikely to grow much
  • suitably large (more than 10, 50, 100 elements, depending on the algorithm)
  • you will be doing lots of indexing into it, i.e. you know you will often want the third element, or the fifth, or whatever.

Use a list for:

  • variable length data lists
  • that are mostly used as a stack or a queue or need to be iterated in its entirety

Use a hashmap for:

  • variable length data lists
  • that need to be indexed like an array would

In reality, you'll want a list or hashmap almost all of the time. Next time you pick a data structure, think about what it must do well for you (or your code, anyway). Then pick something based on that. When in doubt, pick something as general as possible, i.e. an interface you can replace the implementation of quite easily. Some good links in the other answers as well.

wds
A: 

If you want to lookup/edit data in random places, use array for speed. If you just need to iterate the collection, or add/remove data, definitely use a (linked) list.

Also Lists for improved memory usage, an array has to be consecutively arranged in memory, so you can lookup the individual array members by getting the address of the array and adding the element's index. This gives a O(1) lookup time for arrays :) A list's lookup time would be O(n).

Sune Rievers