MyClass[] array;
List<MyClass> list;

当一个比另一个更可取的情况是什么?,为什么?


当前回答

因为没有人提到:在c#中,数组是一个列表。MyClass[]和List<MyClass>都实现了IList<MyClass>。(例如void Foo(IList<int> Foo)可以像Foo(new[]{1,2,3})或Foo(new List<int>{1,2,3})一样调用)

因此,如果你正在编写一个接受List<MyClass>作为参数的方法,但只使用功能的子集,你可能想声明为IList<MyClass>,以方便调用者。

细节:

为什么数组实现IList? 如何在c#数组部分实现IList<T>?

其他回答

请记住,使用List是不可能做到这一点的:

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";

它生成一个异常。

相反,使用数组:

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";

但是对于数组,不会自动调整数据结构的大小。您必须手动或使用Array管理它。调整方法。

一个技巧是用一个空数组初始化List。

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

arr[10] = "new string";

但在这种情况下,如果你使用Add方法添加一个新元素,它将被注入到列表的末尾。

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

实际上,我只是想添加一个链接,我很惊讶还没有提到:Eric的Lippert的博客条目“数组被认为有点有害”。

您可以从标题中判断,它建议在任何可行的地方使用集合——但正如Marc正确地指出的那样,在很多地方,数组确实是唯一可行的解决方案。

如果我确切地知道我需要多少元素,比如我需要5个元素,而且只需要5个元素,那么我就使用数组。否则我只使用List<T>。

当集合本身的不可变性是客户端和提供者代码之间契约的一部分时(不一定是集合中项目的不可变性)以及当IEnumerable不合适时,应该优先使用数组而不是List。

例如,

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

很明显,对"strChars"的修改不会改变原始的"str"对象,无论实现级是否了解"str"的底层类型。

但是假设

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

在这种情况下,仅仅从代码片段中还不清楚insert方法是否会改变原始的“str”对象。它需要String的实现级知识来做出判断,这打破了契约式设计方法。在String的情况下,这不是一个大问题,但在几乎所有其他情况下,这可能是一个大问题。将List设置为只读确实有帮助,但会导致运行时错误,而不是编译时错误。

与其对每种数据类型的特性进行比较,我认为最实用的答案是“对于您需要完成的任务来说,差异可能并不那么重要,特别是因为它们都实现了IEnumerable,所以遵循流行的惯例,使用List,直到您有理由不使用List,此时您可能会有理由使用数组而不是List。”

大多数情况下,在托管代码中,您会希望集合尽可能易于使用,而不是担心微观优化。