is there in C# a method for List like resize in c++ for vector

后端 未结 7 1231
無奈伤痛
無奈伤痛 2021-01-03 18:14

When I use resize(int newsize) in C++ for vector, it means that the size of this vector are set to newsize

7条回答
  •  被撕碎了的回忆
    2021-01-03 19:06

    No, but you can use extension methods to add your own. The following has the same behaviour as std::vector::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(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());
        }
    }
    

    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(this List list, int sz)
      {
          Resize(list, sz, default(T));
      }
    

    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(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));
        }
    }
    

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

提交回复
热议问题