当我使用resize(int newsize)
在C ++对vector<T>
则意味着size
此的vector
被设置为newsize
和索引在运行范围[0..newsize)
如何做到在C#中同为List<T>
改变List<T>
属性Capacity
仅改变Capacity
,但离开该Count
是相同的,并且此外,索引仍然在范围[0..Count)
帮我个忙,请。
PS想象我有一个vector<T> tmp
与tmp.size() == 5
我不能引用tmp[9]
但是当我然后使用tmp.resize(10)
我可以指tmp[9]
在C#,如果我有List<T> tmp
与tmp.Count == 5
我不能引用tmp[9]
IndexOutOfRangeException
),但即使当我设置tmp.Capacity=10
我将无法指tmp[9]
的堂妹tmp.Count
还是5.我想找到在C#调整大小的一些比喻。
没有,但你可以使用扩展方法来添加自己的。 以下具有相同的行为std::vector<T>::resize()
包括相同的时间复杂度。 唯一的区别是,在C ++中,我们可以定义一个默认的void resize ( size_type sz, T c = T() )
的方式和模板的工作意味着那很好,如果我们把它叫做没有默认的T
不具有可访问的参构造函数。 在C#中,我们不能做到这一点,所以我们反而要创建一个方法,没有约束的非默认使用的情况相匹配,另一个与where new()
调用到它的约束。
public static class ListExtra
{
public static void Resize<T>(this List<T> 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<T>(this List<T> 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<T>(this List<T> list, int sz)
{
Resize(list, sz, default(T));
}
这与值类型(调用参数的构造函数)相同的效果,但与引用类型,它会用空值填充。 在这种情况下,我们就可以重写整个类:
public static class ListExtra
{
public static void Resize<T>(this List<T> 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<T>
和List<T>
约在指针如何在C中使用++和C#的差异。
只是为了让乔恩·汉娜的回答更具可读性:
public static class ListExtras
{
// list: List<T> to resize
// size: desired new size
// element: default value to insert
public static void Resize<T>(this List<T> 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<T>.Capacity
就像使用std::vector<T>.reserve(..)
也许List<T>.AddRange(..)
满足您的需求。
这是我的解决方案。
private void listResize<T>(List<T> list, int size)
{
if (size > list.Count)
while (size - list.Count > 0)
list.Add(default<T>);
else if (size < list.Count)
while (list.Count - size > 0)
list.RemoveAt(list.Count-1);
}
当size
和list.Count
都是一样的,没有必要调整名单。
该default(T)
的参数是用来代替null
, ""
, 0
或其他可空类型,在列表中,以填补空白的项目,因为我们不知道什么类型的<T>
的(参考,值,结构等。 )。
PS我用for
循环,而不是while
循环和我遇到了一个问题。 没有永远的列表的大小是我是要求。 这是较小的。 任何想法,为什么?
核实:
private void listResize<T>(List<T> 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); }
你有没有在MSDN阅读: -
列表是项目的一个可调整大小的集合 。 列表可以构建多种方式,但最有用的类列表。 这可以让你强类型的列表,包括所有用于处理收集的基本功能,并可以很容易地搜索。
进一步:-
容量是列表可需要调整之前存储元件的数量,而伯爵是实际在列表中元素的个数。
能力始终大于或等于计数。 如果计数超过容量添加元素时,容量增加复制旧的元素和添加新元素之前自动重新分配内部阵列 。