Friday, May 21, 2010

How can i make a dynamic array in c#?

Quite often you want to create a method that returns an array of a given type. In most cases you don't know the number of elements of that array up front (e.g., when returning data from the database). The problem is that when you declare an array in C#, you must specify the number of elements of that array. The following code snippet shows a declaration of an array of strings with 10 elements.





Array declaration in C#


string[] aFoo = new string[9];


One way to go about this problem would be to create an array big enough to make it improbable that the actual number of elements exceeds its size.





Oversize array


public string[] GetFoo() {


// Your guess is that the number of elements returned never exceeds 1001


string[] tmp = new string[1000];


int i = 0;


// Connect to the database and create a data reader (myReader)


while (myReader.Read()) {


// Do some cools stuff here


tmp[i] = (string) myReader["name"];


i++;


}


return tmp;


}


Yes, that certainly would work. However, in most cases you'll be simply wasting memory. The more you want to reduce the risk that the array is undersized, the more memory you're wasting. Yet, you can only reduce the risk, not eliminate it. Plus, let's be frank, this approach is not very elegant.





What we need is a way to extend our array dynamically. That's where the ArrayList enters the building. You will find it in the System.Collections namespace. ArrayList can be filled with any number of elements (by means of the Add method) and provides a method that returns an array of these elements. That's exactly what we're after.





Dynamic arrays with ArrayList


public string[] GetFoo() {


System.Collections.ArrayList al = new ArrayList();


// Connect to the database and create a data reader (myReader)


while (myReader.Read()) {


// Do some cools stuff here


al.Add((string) myReader["name"]);


}


return (string[]) al.ToArray(typeof(string));


}


As you can see we're adding elements to the ArrayList object as many times as required. If the while loop iterates 3 times, we will have 3 elements. If it iterates 1003 times, we will have 1003 elements.





One thing that probably is not straight forward at the first glance is the last line of code where we return the array. Let's have a closer look at it. The ToArray method expects on parameter of the type Type (there is also a no-parameter overload that returns an array of objects). Since we want an array of strings, we need to pass the type of string, thus typeof(string). The return type of the ToArray method is object[]. The reason for that is obvious--this method can return arrays of any type so it must use the least common denominator and in terms of the object hierarchy it's the object type. However, the returned array has an inner type and we need to tell the compiler that we refer to it. That's why we use the casting expression (string[]) and establish a match between the return type of our method and of the object we return.





The aforementioned feature of the ToArray method--its ability to return arrays of any type--can be also employed to return arrays of a custom type. In the following code snippet we first delcare a custom class. Then we rewrite our GetFoo method to return arrays of that custom type.





Dynamic arrays of custom type with ArrayList


public class MyCustomClass {


public MyCustomClass(string myProperty) {


_MyProperty = myProperty;


}


public string MyProperty {


get {


return _MyProperty;


}


set {


_MyProperty = value;


}


}


private _MyProperty;


}





// ...





public MyCustomClass[] GetFoo() {


System.Collections.ArrayList al = new ArrayList();


MyCustomClass myClass;


// Connect to the database and create a data reader (myReader)


while (myReader.Read()) {


// Do some cools stuff here


myClass = new MyCustomClass((string) myReader["name"]);


al.Add(myClass);


}


return (MyCustomClass[]) al.ToArray(typeof(MyCustomClass));


}

How can i make a dynamic array in c#?
Use one of the collection classes like ArrayList, or use Generics.

credit cards

No comments:

Post a Comment