在C#中有List< T>的方法例如在c ++中为向量< T> [英] is there in C# a method for List<T> like resize in c++ for vector<T>

查看:255
本文介绍了在C#中有List< T>的方法例如在c ++中为向量< T>的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我在C ++中为向量< T> 使用 resize(int newsize)时,此向量的code> size 设置为 newsize 在范围 [0..newsize)。如何在C#中为列表< T> 执行相同的操作?

更改列表< T> 属性容量仅更改容量,但保留 Count 相同,此外索引仍然在范围 [0..Count)。请帮助我。

When I use resize(int newsize) in C++ for vector<T>, it means that the size of this vector are set to newsize and the indexes run in range [0..newsize). How to do the same in C# for List<T>?
Changing the List<T> property Capacity only changes the Capacity but leaves the Count the same, and furthermore the indexes still are in range [0..Count). Help me out, please.

想象一下我有一个向量< 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] coz的 tmp.Count 还是5.我想在C#中找到一些类似resize。

P.S. Imagine I have a vector<T> tmp with a tmp.size() == 5 I cannot refer to tmp[9], but when I then use tmp.resize(10) I may refer to tmp[9]. In C# if I have List<T> tmp with tmp.Count == 5 I cannot refer to tmp[9] (IndexOutOfRangeException), but even when I set tmp.Capacity=10 I will not be able to refer to tmp[9] coz of tmp.Count is still 5. I want to find some analogy of resize in C#.

推荐答案

不,但您可以使用扩展方法添加自己的。以下具有与 std :: vector< T> :: resize()相同的行为,包括相同的时间复杂度。唯一的区别是,在C ++中,我们可以使用 void resize(size_type sz,T c = T())定义一个默认值,在没有没有可访问无参数构造函数的 T 的默认情况下调用它。在C#中,我们不能这样做,所以我们必须创建一个没有约束匹配非默认使用情况的方法,另一个方法使用其中new()约束,调用它。

No, but you can use extension methods to add your own. The following has the same behaviour as std::vector<T>::resize(), including the same time-complexity. The only difference is that in C++ we can define a default with void resize ( size_type sz, T c = T() ) and the way templates work means that that's fine if we call it without the default for a T that has no accessible parameterless constructor. In C# we can't do that, so instead we have to create one method with no constraint that matches the non-default-used case, and another with a where new() constraint that calls into it.

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()产生一个空指针(因为它是一个指针)的情况下,这里我们期望它调用一个无参数的构造函数。因此,你可能会发现它更接近你用来替换第二个方法的行为:

Now the likes of myList.Resize(23) or myList.Resize(23, myDefaultValue) will match what one expects from C++'s vector. I'd note though that sometimes where with C++ you'd have a vector of pointers, in C# you'd have a list of some reference-type. Hence in cases where the C++ T() produces a null pointer (because it's a pointer), here we're expecting it to call a parameterless constructor. For that reason you might find it closer to the behaviour you're used to to replace the second method with:

  public static void Resize<T>(this List<T> list, int sz)
  {
      Resize(list, sz, default(T));
  }

这对于值类型(调用无参数构造函数)有同样的效果,引用类型,它将填充null。在这种情况下,我们可以将整个类重写为:

This has the same effect with value types (call parameterless constructor), but with reference-types, it'll fill with nulls. In which case, we can just rewrite the entire class to:

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#。

Note that this isn't so much about differences between std::vector<T> and List<T> as about the differences in how pointers are used in C++ and C#.

这篇关于在C#中有List&lt; T&gt;的方法例如在c ++中为向量&lt; T&gt;的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆