.NET提供了一个通用的列表容器,其性能几乎相同(请参见阵列性能与列表性能问题)。但是,它们在初始化方面大不相同。
数组很容易使用默认值初始化,并且根据定义,它们已经具有一定的大小:
string[] Ar = new string[10];
这样可以安全地分配随机项目,例如:
Ar[5]="hello";
使用列表,事情比较棘手。我可以看到执行相同初始化的两种方法,这两种都不是您所说的优雅:
List<string> L = new List<string>(10); for (int i=0;i<10;i++) L.Add(null);
要么
string[] Ar = new string[10]; List<string> L = new List<string>(Ar);
什么是更清洁的方式?
编辑:到目前为止,答案是关于容量的,这与预填充列表不同。例如,在刚创建的容量为10的列表上,一个不能执行L[2]="somevalue"
L[2]="somevalue"
编辑2:人们想知道为什么我要以这种方式使用列表,因为这不是他们打算使用的方式。我可以看到两个原因:
令人信服的是,列表是“下一代”数组,几乎没有损失,但却增加了灵活性。因此,默认情况下应使用它们。我指出,它们可能不那么容易初始化。
我当前正在编写的是一个基类,该基类提供默认功能,作为更大框架的一部分。在我提供的默认功能中,列表的大小是高级已知的,因此我可以使用数组。但是,我想为任何基类提供动态扩展它的机会,因此我选择了一个列表。
我不能说我经常需要-您能否提供更多为什么要这样做的详细信息?我可能会将其作为静态方法放在帮助器类中:
public static class Lists { public static List<T> RepeatedDefault<T>(int count) { return Repeated(default(T), count); } public static List<T> Repeated<T>(T value, int count) { List<T> ret = new List<T>(count); ret.AddRange(Enumerable.Repeat(value, count)); return ret; } }
您 可以 使用,Enumerable.Repeat(default(T), count).ToList()但是由于缓冲区大小调整,效率会很低。
Enumerable.Repeat(default(T), count).ToList()
请注意,如果T是引用类型,它将存储count为value参数传递的引用的副本- 因此它们都将引用同一对象。这可能取决于您的用例,也可能不是您想要的。
T
count
value
编辑:如注释中所述,如果需要,您可以Repeated使用循环来填充列表。那也会稍微快一点。我个人认为代码使用的是Repeat更具描述性的,并且怀疑在现实世界中,性能差异是无关紧要的,但是您的工作量可能会有所不同。
Repeated
Repeat