当我使用 resize(int newsize)
时在 C++ 中为 vector<T>
,这意味着 size
这个vector
设置为 newsize
并且索引在 [0..newsize)
范围内运行.如何在 C# 中为 List<T>
做同样的事情?
更改 List<T>
特性 Capacity
仅更改 Capacity
但离开 Count
相同,而且索引仍在 [0..Count)
范围内.请帮帮我。
附:想象一下,我有一个 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# 中找到一些 resize 的类比。
最佳答案
不,但您可以使用扩展方法添加自己的。以下与 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++ vector 的期望。我会注意到,有时在 C++ 中你会有一个指针 vector ,在 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# 中使用方式的差异。
关于c# - C# 中是否有 List<T> 的方法,例如在 c++ 中为 vector<T> 调整大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12231569/