Reputation: 20843
In Hosam Aly's answer to the question "Set/extend List length in C#" this code is proposed:
public static List<T> EnsureSize<T>(this List<T> list, int size, T value)
{
if (list == null) throw new ArgumentNullException("list");
if (size < 0) throw new ArgumentOutOfRangeException("size");
int count = list.Count;
if (count < size)
{
int capacity = list.Capacity;
if (capacity < size)
list.Capacity = Math.Max(size, capacity * 2);
while (count < size)
{
list.Add(value);
++count;
}
}
return list;
}
where the value is added to the list by reference. How can on ensure the size of a list by using copies instead?
(I tried to use Clone()
and ICloneable
without success, since some types, e.g. List<T>
return a shallow copy and I want a deep copy.)
Upvotes: 1
Views: 91
Reputation: 77304
As long as you don't know anything about T, whether it's clonable or serializable or a million other ways to copy it, you will have to rely on the caller to provide such means. You want an arbitrary number of new T's, the the simplest version would be to ask for a generator in your method signature:
public static List<T> EnsureSize<T>(this List<T> list, int size, Func<T> generator)
{
if (list == null) throw new ArgumentNullException("list");
if (size < 0) throw new ArgumentOutOfRangeException("size");
int count = list.Count;
if (count < size)
{
int capacity = list.Capacity;
if (capacity < size)
list.Capacity = Math.Max(size, capacity * 2);
while (count < size)
{
list.Add(generator());
++count;
}
}
return list;
}
Calling it would look like this:
myList.EnsureSize(42, () => new Item());
or this:
myList.EnsureSize(42, () => existingItem.Clone());
or maybe this:
myList.EnsureSize(42, () => StaticItemFactory.CreateNew());
or any other way to construct a new T.
Upvotes: 4