Array sizing

  • Thread starter Thread starter Neil B
  • Start date Start date
N

Neil B

In C++ arrays have the .SetAtGrow() method that expands the array to
accommodate the index specified. I don't find an equivalent method in C#.

Is there one??

If not, what is the recommended way to handle this??
Currently I'm using the Resize(....) method but this can be awkward at times.

Thanks, Neil
 
Neil said:
In C++ arrays have the .SetAtGrow() method that expands the array to
accommodate the index specified.

You're talking about the MFC CArray class. That's not the same thing as a
"C++ array". C++ has plain old C arrays, but those don't grow.
I don't find an equivalent method in C#.

Is there one??
No. Array objects are immutable in C# (their contents are not, of course).
If not, what is the recommended way to handle this??

Use a List<T> instead. (That's not a linked list, contrary to what you might
think, it's the equivalent of an STL vector.)

List<T> has no way of automatically expanding to a specified index, but it's
easy enough to achieve. Here's an extension method in C# 3 that will achieve
the same as CArray::SetAtGrow:

public static void SetAtGrow<T>(this List<T> list, int index, T item) {
if (list.Count > index) return;
if (list.Capacity < index) list.Capacity = index;
list.AddRange(Forever(default(T)).Take(index - list.Count));
list.Add(item);
}

public static IEnumerable<T> Forever<T>(T item) {
while (true) yield return item;
}

If you're going to do this a lot, you'll want to set .Capacity to a
reasonable value before, to minimize reallocations. If the list you're going
Currently I'm using the Resize(....) method but this can be awkward at times.
I'll say. It'll be especially awkward for performance. .Resize() does not
actually resize an array, it creates a brand new one -- the documentation
explains this.
 
In C++ arrays have the .SetAtGrow() method that expands the array to
accommodate the index specified. I don't find an equivalent method in C#.

Is there one??
No

If not, what is the recommended way to handle this??
Currently I'm using the Resize(....) method but this can be awkward at times.
Thanks, Neil

Use a List<T> collection.
 
Jeroen said:
public static void SetAtGrow<T>(this List<T> list, int index, T item) {
if (list.Count > index) return;
if (list.Capacity < index) list.Capacity = index;
list.AddRange(Forever(default(T)).Take(index - list.Count));
list.Add(item);
}
Heh. That's what you get for modifying your code halfway through. The
obvious fix:

public static void SetAtGrow<T>(this List<T> list, int index, T newElement) {
if (index < list.Count) {
list[index] = newElement;
return;
}
if (list.Capacity < index) list.Capacity = index;
list.AddRange(Forever(default(T)).Take(index - list.Count));
list.Add(newElement);
}
 
Jeroen said:
Jeroen said:
public static void SetAtGrow<T>(this List<T> list, int index, T item) {
if (list.Count > index) return;
if (list.Capacity < index) list.Capacity = index;
list.AddRange(Forever(default(T)).Take(index - list.Count));
list.Add(item);
}
Heh. That's what you get for modifying your code halfway through. The
obvious fix:

public static void SetAtGrow<T>(this List<T> list, int index, T
newElement) {
if (index < list.Count) {
list[index] = newElement;
return;
}
if (list.Capacity < index) list.Capacity = index;
list.AddRange(Forever(default(T)).Take(index - list.Count));
list.Add(newElement);
}
*sigh* The above code still contains one more bug, but this one is left as
an exercise to the reader, as I obviously need some refreshments.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Back
Top