在c#中设置/扩展List 长度

给定c#中的List是否有一种方法可以扩展它(在其容量内)并将新元素设置为null ? 我想要一些像memset一样的东西。 我不是在寻找糖,我想要快速的代码。 我知道在C中,操作可以在每个条目1-3个asm操作中完成。

我发现的最佳解决方案是:

 list.AddRange(Enumerable.Repeat(null, count-list.Count)); 

然而,这是c#3.0(首选<3.0),可能正在生成和评估枚举器。

我目前的代码使用:

 while(list.Count < lim) list.Add(null); 

所以这是时间成本的起点。

这样做的动机是我需要设置第n个元素,即使它是在旧的Count之后。

最简单的方法可能是创建一个临时数组:

 list.AddRange(new T[size - count]); 

其中size是所需的新大小, count是列表中的项目数。 但是,对于相对较大的size - countsize - count ,这可能会导致性能不佳,因为它可能导致列表重新分配多次。 * )它还有一个缺点,即分配一个额外的临时数组,根据您的要求,这可能是不可接受的。 您可以使用以下方法以更明确的代码为代价来缓解这两个问题:

 public static class CollectionsUtil { public static List EnsureSize(this List list, int size) { return EnsureSize(list, size, default(T)); } public static List EnsureSize(this List list, int size, T value) { if (list == null) throw new ArgumentNullException("list"); if (size < 0) throw new ArgumentOutOfRangeException("size"); int count = list.Count; if (count < size) { int capacity = list.Capacity; if (capacity < size) list.Capacity = Math.Max(size, capacity * 2); while (count < size) { list.Add(value); ++count; } } return list; } } 

这里唯一的C#3.0是使用“ this ”修饰符来使它们成为扩展方法。 删除修饰符,它将在C#2.0中工作。

不幸的是,我从未比较过两个版本的性能,所以我不知道哪一个更好。

哦,你知道你可以通过调用Array.Resize调整数组的大小吗? 我不知道。 🙂

更新:
* )使用list.AddRange(array) 不会导致使用枚举器。 通过Reflector进一步查看显示该数组将被转换为ICollection ,并且将使用Count属性,以便仅分配一次。

 static IEnumerable GetValues(T value, int count) { for (int i = 0; i < count; ++i) yield return value; } list.AddRange(GetValues(null, number_of_nulls_to_add)); 

这将适用于2.0+

你为什么要那样做? List的主要优点是它可以根据需要增长,那么为什么要为它添加一些null或default元素呢?

在这种情况下使用数组不是更好吗?