在C#中有一个List 的方法,比如在c ++中为vector 重新resize
当我在C ++中对vector
使用resize(int newsize)
时,意味着此vector
的size
设置为newsize
,索引在范围[0..newsize)
运行。 如何在C#中为List
做同样的事情?
更改List
属性Capacity
仅更改Capacity
但使Count
保持不变,此外索引仍在[0..Count)
范围内。 请帮帮我。
PS想象一下我有一个vector tmp
与tmp.size() == 5
我不能参考tmp[9]
,但是当我然后使用tmp.resize(10)
我可以参考tmp[9]
。 在C#中如果我有List tmp
和tmp.Count == 5
我不能引用tmp[9]
( IndexOutOfRangeException
),但即使我设置tmp.Capacity=10
我也无法引用tmp[9]
因为tmp.Count
仍然是5.我想在C#中找到一些resize的类比。
不,但您可以使用扩展方法添加自己的。 以下内容与std::vector
具有相同的行为,包括相同的时间复杂度。 唯一的区别是在C ++中我们可以使用void resize ( size_type sz, T c = T() )
定义一个默认值,而模板的工作方式意味着如果我们调用它没有默认情况下没有可访问无参数的T
那就没问题构造函数。 在C#中我们不能这样做,所以我们必须创建一个没有约束的方法,该方法与非默认使用的情况相匹配,另一个方法创建一个调用它的where new()
约束。
public static class ListExtra { public static void Resize(this List list, int sz, T c) { int cur = list.Count; if(sz < cur) list.RemoveRange(sz, cur - sz); else if(sz > cur) { if(sz > list.Capacity)//this bit is purely an optimisation, to avoid multiple automatic capacity changes. list.Capacity = sz; list.AddRange(Enumerable.Repeat(c, sz - cur)); } } public static void Resize (this List list, int sz) where T : new() { Resize(list, sz, new T()); } }
现在像myList.Resize(23)
或myList.Resize(23, myDefaultValue)
这样的东西将匹配C ++的向量所期望的。 我注意到,有时在C ++中你会有一个指针向量,在C#中你会得到一些引用类型的列表。 因此,在C ++ T()
产生空指针(因为它是指针)的情况下,这里我们期望它调用无参数构造函数。 出于这个原因,您可能会发现它更接近您习惯用以下方法替换第二个方法的行为:
public static void Resize(this List list, int sz) { Resize(list, sz, default(T)); }
这与值类型(调用无参数构造函数)具有相同的效果,但对于引用类型,它将填充空值。 在这种情况下,我们可以将整个类重写为:
public static class ListExtra { public static void Resize(this List list, int sz, T c = default(T)) { int cur = list.Count; if(sz < cur) list.RemoveRange(sz, cur - sz); else if(sz > cur) list.AddRange(Enumerable.Repeat(c, sz - cur)); } }
请注意,这不是关于std::vector
和List
的区别,而是关于指针在C ++和C#中的使用方式的差异。
只是为了让Jon Hanna的回答更具可读性:
public static class ListExtras { // list: List to resize // size: desired new size // element: default value to insert public static void Resize (this List list, int size, T element = default(T)) { int count = list.Count; if (size < count) { list.RemoveRange(size, count - size); } else if (size > count) { if (size > list.Capacity) // Optimization list.Capacity = size; list.AddRange(Enumerable.Repeat(element, size - count)); } } }
抱歉。 这是你需要的吗? List.TrimExcess()
设置List
就像使用std::vector
。 也许List
符合您的需求。
你有没有在MSDN上阅读: –
列表是可resize的项目集合 。 列表可以通过多种方式构建,但最有用的类是List。 这允许您强烈键入列表,包括处理集合的所有基本function,并且可以轻松搜索。
进一步:-
Capacity是在需要resize之前List可以存储的元素数,而Count是List中实际存在的元素数。
容量始终大于或等于Count。 如果Count在添加元素时超出容量,则在复制旧元素和添加新元素之前,通过自动重新分配内部数组来增加容量 。
这是我的解决方案。
private void listResize(List list, int size) { if (size > list.Count) while (size - list.Count > 0) list.Add(default ); else if (size < list.Count) while (list.Count - size > 0) list.RemoveAt(list.Count-1); }
当size
和list.Count
相同时,无需调整列表大小。
使用default(T)
参数而不是null
, ""
, 0
或其他可空类型来填充列表中的空项,因为我们不知道
是什么类型(引用,值,结构等)。 )。
PS我用于循环而不是
while
循环,我遇到了一个问题。 并不总是列表的大小是我要求的。 它更小。 有什么想法?核实:
private void listResize
(List list, int size) { if (size > list.Count) for (int i = 0; i <= size - list.Count; i++) list.Add(default(T)); else if (size < list.Count) for (int i = 0; i <= list.Count - size; i++) list.RemoveAt(list.Count-1); }
列表没有有限的大小。
这个尺寸对你来说有什么原因吗?
也许数组或字典更接近您的要求