在 C# 中设置/扩展 List<T> 长度
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/481603/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Set/extend List<T> length in c#
提问by BCS
Given a List<T>
in c# is there a way to extend it (within its capacity) and set the new elements to null
? I'd like something that works like a memset
. I'm not looking for sugar here, I want fast code. I known that in C the operation could be done in something like 1-3 asm ops per entry.
给定List<T>
c# 中的 a 有没有办法扩展它(在其能力范围内)并将新元素设置为null
?我想要一些像memset
. 我不是在这里寻找糖,我想要快速的代码。我知道在 C 中,操作可以像每个条目 1-3 个 asm ops 那样完成。
The best solution I've found is this:
我已经找到了最好的解决方案是这样:
list.AddRange(Enumerable.Repeat(null, count-list.Count));
however that is c# 3.0 (<3.0 is preferred) and might be generating and evaluating an enumerator.
然而,这是 c# 3.0(<3.0 是首选)并且可能正在生成和评估枚举数。
My current code uses:
我当前的代码使用:
while(list.Count < lim) list.Add(null);
so that's the starting point for time cost.
所以这是时间成本的起点。
The motivation for thisis that I need to set the n'th element even if it is after the old Count.
这样做的动机是我需要设置第 n 个元素,即使它在旧 Count 之后。
采纳答案by Hosam Aly
The simplest way is probably by creating a temporary array:
最简单的方法可能是创建一个临时数组:
list.AddRange(new T[size - count]);
Where size
is the required new size, and count
is the count of items in the list. However, for relatively large values of (size - count
, this can have bad performance, since it can cause the list to reallocate multiple times.*
) It also has the disadvantage of allocating an additional temporary array, which, depending on your requirements, may not be acceptable. You could mitigate both issues at the expense of more explicit code, by using the following methods:
哪里size
是所需的新大小,count
是列表中的项目数。但是,对于相对较大的 值( size - count
,这可能会导致性能不佳,因为它可能导致列表多次重新分配。*
) 它还具有分配额外的临时数组的缺点,根据您的要求,这可能是不可接受的。您可以通过使用以下方法以更明确的代码为代价来缓解这两个问题:
public static class CollectionsUtil
{
public static List<T> EnsureSize<T>(this List<T> list, int size)
{
return EnsureSize(list, size, default(T));
}
public static List<T> EnsureSize<T>(this List<T> 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;
}
}
The only C# 3.0 here is the use of the "this
" modifier to make them extension methods. Remove the modifier and it will work in C# 2.0.
此处唯一的 C# 3.0 是使用“ this
”修饰符使它们成为扩展方法。删除修饰符,它将在 C# 2.0 中工作。
Unfortunately, I never compared the performance of the two versions, so I don't know which one is better.
遗憾的是,我从来没有比较过这两个版本的性能,所以我不知道哪个更好。
Oh, and did you know you could resize an array by calling Array.Resize<T>
? I didn't know that. :)
哦,你知道你可以通过调用来调整数组的大小Array.Resize<T>
吗?我不知道。:)
Update:
(*
) Using list.AddRange(array)
will notcause an enumerator to be used. Looking further through Reflector showed that the array will be casted to ICollection<T>
, and the Count
property will be used so that allocation is done only once.
更新:
(*
)使用list.AddRange(array)
会不会导致枚举使用。通过 Reflector 进一步查看显示,该数组将被强制转换为ICollection<T>
,并且Count
将使用该属性,以便仅进行一次分配。
回答by Frederik Gheysels
Why do you want to do that ? The main advantage of a List is that it can grow as needed, so why do you want to add a number of null or default elements to it ?
你为什么要这样做?List 的主要优点是它可以根据需要增长,那么为什么要向其中添加许多 null 或默认元素呢?
Isn't it better that you use an array in this case ?
在这种情况下使用数组不是更好吗?
回答by Mehrdad Afshari
static IEnumerable<T> GetValues<T>(T value, int count) {
for (int i = 0; i < count; ++i)
yield return value;
}
list.AddRange(GetValues<object>(null, number_of_nulls_to_add));
This will work with 2.0+
这将适用于 2.0+