Array versus List: When to use which?

2018-12-31 03:39发布

MyClass[] array;
List<MyClass> list;

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

标签: .net arrays list
15条回答
看风景的人
2楼-- · 2018-12-31 03:56

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.

查看更多
流年柔荑漫光年
3楼-- · 2018-12-31 03:57

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
  • when you do not want to write an expression to derive the ultimate array size for the declaration and you do not want to wastefully pick a large number

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.

查看更多
妖精总统
4楼-- · 2018-12-31 03:57

Another situation not yet mentioned is when one will have a large number of items, each of which consists of a fixed bunch of related-but-independent variables stuck together (e.g. the coordinates of a point, or the vertices of a 3d triangle). An array of exposed-field structures will allow the its elements to be efficiently modified "in place"--something which is not possible with any other collection type. Because an array of structures holds its elements consecutively in RAM, sequential accesses to array elements can be very fast. In situations where code will need to make many sequential passes through an array, an array of structures may outperform an array or other collection of class object references by a factor of 2:1; further, the ability to update elements in place may allow an array of structures to outperform any other kind of collection of structures.

Although arrays are not resizable, it is not difficult to have code store an array reference along with the number of elements that are in use, and replace the array with a larger one as required. Alternatively, one could easily write code for a type which behaved much like a List<T> but exposed its backing store, thus allowing one to say either MyPoints.Add(nextPoint); or MyPoints.Items[23].X += 5;. Note that the latter would not necessarily throw an exception if code tried to access beyond the end of the list, but usage would otherwise be conceptually quite similar to List<T>.

查看更多
流年柔荑漫光年
5楼-- · 2018-12-31 03:58

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

查看更多
看风景的人
6楼-- · 2018-12-31 04:00

Since no one mention: in C#, an array is a list. MyClass[] and List<MyClass> both implement IList<MyClass>.

So, if you are writing method that accepts one as an argument but uses only limited aspect, you may be able to declare it as IList<MyClass> for callers' convenience. (e.g. Foo(IList<int> foo) can be called like Foo(new[] { 1, 2, 3 }) or Foo(new List<int> { 1, 2, 3 }) )

Details:

查看更多
旧时光的记忆
7楼-- · 2018-12-31 04:02

Arrays should be used in preference to List when the immutability of the collection itself is part of the contract between the client & provider code (not necessarily immutability of the items within the collection) AND when IEnumerable is not suitable.

For example,

var str = "This is a string";
var strChars = str.ToCharArray();  // returns array

It is clear that modification of "strChars" will not mutate the original "str" object, irrespective implementation-level knowledge of "str"'s underlying type.

But suppose that

var str = "This is a string";
var strChars = str.ToCharList();  // returns List<char>
strChars.Insert(0, 'X');

In this case, it's not clear from that code-snippet alone if the insert method will or will not mutate the original "str" object. It requires implementation level knowledge of String to make that determination, which breaks Design by Contract approach. In the case of String, it's not a big deal, but it can be a big deal in almost every other case. Setting the List to read-only does help but results in run-time errors, not compile-time.

查看更多
登录 后发表回答