Dynamically change size of Array type and IEnumerable

J

Jon Slaughter

Is it possible to dynamically change the number of elements of one of those
types without actually knowing the element type?

Say I have a

int[] l = new int[30];

But later on in my code I have an object that I know is an array or because
I have

if (s is Array)
{

}

But I do not know what element type it uses... (l could be char's, bytes, or
anything). All I do know is that its an array. (another problem is the
dimensionality)

What I want to do is increase the size of s but since I do not know what
type it is I can't simply use new. I can do something like

if (s is Array)
{

object o = new s.GetType().ElementType()[40];
}

But of course that doesn't work.


I'm sure there is a solution(maybe unsafe code) but haven't been able to
figure it out.

Array does have CreateInstance which seems to do what I want but there then
is the issue with dimensionality.

----------

Heres basically what I'm trying to do(not exactly but is equivalent and
shows the problem).

I have a binary file of numbers. The numbers are arbitrary. I want to supply
the user with a function that they can load the data into arbitrary arrays.

So they might do something like

int[] A;
Load(A);

or

float[] B;
Load(B);

or even

some_class[][][] C;

(its not so arbitrary as the file does have info about the structure of the
arrays and its suppose to correspond to what the user passes but both must
be general enough to handle the different dimensions and element types)


Infact the argument to load is passed as an object because they might just
want to load a single value type or something else. Again, its more
complicated and this example doesn't really show why I'm trying to do what I
do but does show the problem I'm running up against.

Thanks,
Jon
 
M

Marc Gravell

First; you cannot change the size of an Array. You can create a new Array
and copy the values over, however.
But I do not know what element type it uses... ...
object o = new s.GetType().ElementType()[40];
But of course that doesn't work.

Example for 1-D arrays below. Note I've also included the same using
generics and type-inference. If you can use it, this is an easier option.
or even
some_class[][][] C;

You mention dimension several times; for the record, that is a jagged array,
where all the component arrays have dimension 1. A multi-dimensional array
would be something like some_class[,] or some_class[,,].

You can create multi-dimensional arrays with CreateInstance, but copying the
data is a pain, as you can't simply blit.

Marc

public static class ArrayExt
{
// note: extension methods "just because"; they could equally be
// regular static utility methods
public static T[] ReDim<T>(this T[] array, int length)
{
RedimCheckArray(array);
T[] newArray = new T[length];
Array.Copy(array, newArray, length < array.Length ? length :
array.Length);
return newArray;
}
public static Array ReDim(this Array array, int length)
{
RedimCheckArray(array);
Array newArray =
Array.CreateInstance(array.GetType().GetElementType(), length);
Array.Copy(array, newArray, length < array.Length ? length :
array.Length);
return newArray;
}
private static void RedimCheckArray(Array array)
{
if (array == null) throw new ArgumentNullException("array");
if (array.Rank != 1)
{
throw new ArgumentException("Array must be 1-dimensional",
"array");
}
if (array.GetLowerBound(0) != 0)
{
throw new ArgumentException("Array must be 0-based", "array");
}
}
}
class ArrayDemo
{
static void Main()
{
// sample data
int[] foo = { 1, 2, 3, 4, 5 };

// try generic form using inference
int[] bar = foo.ReDim(7);

// try non-generic form
Array arr = bar;
Array arr2 = arr.ReDim(3);
}

}
 
J

Jon Slaughter

Marc Gravell said:
First; you cannot change the size of an Array. You can create a new Array
and copy the values over, however.
But I do not know what element type it uses... ...
object o = new s.GetType().ElementType()[40];
But of course that doesn't work.

Example for 1-D arrays below. Note I've also included the same using
generics and type-inference. If you can use it, this is an easier option.
or even
some_class[][][] C;

You mention dimension several times; for the record, that is a jagged
array, where all the component arrays have dimension 1. A
multi-dimensional array would be something like some_class[,] or
some_class[,,].

Cause I meant to include all types but just didn't give an example. So you
can have marray[,,,,] as a potential possibility.
You can create multi-dimensional arrays with CreateInstance, but copying
the data is a pain, as you can't simply blit.

Yes, thats what I'm trying to handle. The general case of a array(for all
types of arrays). With mdim arrays I guess I could use recursion or
something to copy but I haven't thought about it too much ;/

I like the idea of extensions. I am trying to stay with .NET 2.0 for some
reason but I didn't know 3.5 had the ability to extend like this. Its pretty
cool and I'll have to read up on it. I might have to rethink my own way of
doing this.

Thanks,
Jon
 
M

Marc Gravell

For the record, you can use extension methods with .NET 2.0 (SP1) by
using the 3.5 compiler (the C# 3 compiler) and targetting NET 2.0; you
need to declare a particular attribute yourself, but that is trivial.

Marc
 

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

Top