不,但您可以使用扩展方法添加您自己的。以下具有与 相同的行为std::vector<T>::resize()
,包括相同的时间复杂度。唯一的区别是,在 C++ 中,我们可以定义一个默认值,void resize ( size_type sz, T c = T() )
模板的工作方式意味着如果我们在T
没有可访问的无参数构造函数的 a 的默认值的情况下调用它,那很好。在 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));
}
}
请注意,这与其说是关于 C++ 和 C# 中指针使用方式之间的差异std::vector<T>
,不如说是关于指针使用方式的差异。List<T>