我想转换
var aList = new List<string>(new string[] { "elem1", "elem2", "elem3" });
初始化为
var aList = new List<string>() { "elem1", "elem2", "elem3" };
在我们的源代码中。我相信后者没有不必要的数组创建和数组 - &gt;列表转换。还是前者呢?或者编译器无论如何都要优化它?我以后可以面对任何不良副作用(或没有副作用)吗?
该项目使用.NET 4。
答案 0 :(得分:4)
它们并不完全等同。
在第一种情况下,您正在创建一个新数组,然后将其传递给List<T>
构造函数,该构造函数将创建它自己的相同大小的内部数组并调用源数组的{{1}将项目复制出源数组并进入其内部数组的方法。
在第二种情况下,您构造一个新的CopyTo
,其中包含一个最初为空的数组(大小为List<T>
),然后调用List的_defaultCapacity = 4
方法,这可能会导致内部数组在添加元素时要多次调整大小。
因此,在第一种情况下,您不必调整List的内部数组的大小,以及调用可能更高效的Add
方法,而不是迭代CopyTo
,代价是必须一次在内存中创建两个数组。
您可以做的一件事是避免创建两个数组和确保您没有调整列表内部数组的大小:
Add
由于魔法常量var aList = new List<string>(3) { "elem1", "elem2", "elem3" };
,我不一定会为生产代码推荐这个,但是再一次,你已经有了其他三个魔法常量。
答案 1 :(得分:1)
后者编译成:
aList = new List<string();
aList.Add("elem1");
aList.Add("elem2");
aList.Add("elem3");
构造函数看起来像是在做类似的事情(有一些错误处理):
foreach(var t in items)
Add(t);
换句话说,不需要创建数组。对于微观优化,最好按照您的建议进行优化。但是,实际上,您的结果差别不大。
答案 2 :(得分:1)
如果转换后的代码如下:
var aList = new List<string>(3 /* !capacity specified */) { "elem1", "elem2", "elem3" };
它没有“不必要的数组创建”(如果您指定的不仅仅是List&lt;&gt; :: _ defaultCapacity项目)。
使用三个(或四个)字符串,您的代码也没有“不必要的数组创建”,因为_defaultCapacity == 4.
换句话说,在第二个代码中(带有指定容量的集合初始值设定项),内部List&lt;&gt;的数组可以重新创建几次。