|
May 23rd, 2002
This article shows how to create dynamic arrays 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)); }
Respect, no?
|