C# Array

An array is used to hold a number of variables with the same type. Each variable is called an element of the array and can be accessed through its index. The index starts at zero. For example, We define an array with 5 elements. The first element is element[0] and the last one is element[4].

First and last element of an array

When declaring a single-dimensional array, the syntax can be as follows.

<DataType>[] <ArrayName>;

The DataType can be any data type no matter whether it is a built-in type or an user defined type. The ArrayName can be a variable name as usual.

Arrays are reference typed and an array must be initialized before using it. The new operator can be used to create an Array object and specify how many elements of each dimension we'll use. Once the object is created the length of the elements cannot be changed any more and all the elements will be initialized to their default values. The following example will demonstrate how to initialize an array and how to access each of the elements.

Example 01-79-01

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
using System;

public class MyClass{}

class TestArrayInit
{
    static void Main()
    {
        // Default value of elements in numeric type
        double[] d = new double[5];
        Console.WriteLine("d[0]={0} d[4]={1}", d[0], d[4]);

        // Default value of elements in an user-defined class
        MyClass[] m = new MyClass[3];
        if (m[0] == null)
        {
            Console.WriteLine("The default value is null.");
        }

        // Initialized with values
        int[] i;
        i = new int[6] { 1, 2, 3, 4, 5, 6 };        // new int[] { 1, 2, 3, 4, 5, 6 }; is also OK
        i[0] = 10;
        i[5] = 60;
        Console.WriteLine("i[0]={0} i[5]={1}", i[0], i[5]);

        // Initialized with shortcut style
        string[] s = { "Yesterday", "Today", "Tomorrow" };  // shortcut of new string[]{ "Yesterday", "Today", "Tomorrow" };
        Console.WriteLine("s[1]={0}", s[1]);

        Console.Read();
    }
}

Output

d[0]=0 d[4]=0
The default value is null.
i[0]=10 i[5]=60
s[1]=Today

Explanation

  • Line 10: Create an array d with double type and 5 elements. The number 5 cannot be changed any more after the statement.
  • Line 11: Output the values of the first and last element of the array. d[4] is the last element rather than d[5] and you will get an error message like IndexOutOfRangeException if you use d[5] which does not exist in the array.
  • Line 14-18: Create an array of MyClass with 3 elements. Apparently the default value of each element is null.
  • Line 21: Declare an integer array variable without any initialization.
  • Line 22: Initialized here and number 6 can be omitted.
  • Line 23-24: Change the value of the first and the last element.
  • Line 28: If the initialization combines with its declaration statement, the "new string[]" before curly bracket can be omitted. But if they split up as follows, you will get an error message.
string[] s;	// Declare an array of string
s = { "Yesterday", "Today", "Tomorrow" };  	// Error

Array can be a special data type so it can be transferred as a parameter in a method or returned from a method.

Example 01-79-02

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
using System;

public class MyArray{
    public static int[] getArray()
    {
        return new int[]{ 1, 2, 3 };
    }

    public static void addOne(int[] a)
    {
        for (int i = 0; i < a.Length; i++)
        {
            a[i]++;
        }
        a = null;
    }

    public static void addOneRef(ref int[] a)
    {
        for (int i = 0; i < a.Length; i++)
        {
            a[i]++;
        }
        a = null;
    }

    public static string getOutput(int[] a){
        string result = "{ ";
        for (int i = 0; i < a.Length; i++)
        {
            result += a[i].ToString();
            if (i != a.Length - 1)
            {
                result += ", ";
            }
        }
        result += " }";

        return result;
    }
}

class TestArrayOnMethod
{
    static void Main()
    {
        int[] b = MyArray.getArray();
        Console.WriteLine("b = {0}", MyArray.getOutput(b));

        MyArray.addOne(b);
        if (b != null)
        {
            Console.WriteLine("b = {0}", MyArray.getOutput(b));
        }
        else
        {
            Console.WriteLine("b = null");
        }

        MyArray.addOneRef(ref b);
        if (b != null)
        {
            Console.WriteLine("b = {0}", MyArray.getOutput(b));
        }
        else
        {
            Console.WriteLine("b = null");
        }

        Console.Read();
    }
}

Output

b = { 1, 2, 3 }
b = { 2, 3, 4 }
b = null

Explanation

  • Line 4-7: The return type of the static method is an integer array. Here we just simply create an integer array and return it.
  • Line 9-16: An integer array is used as a parameter and passed into the method. In the method, we go through each element and add 1. a.Length returns the length of the array and in this example, it is 3.
  • Line 15: at last of the method, we'll set the array object points to null in order to see if the array in the calling method is affected or not.
  • Line 18-25: This method is defined the same as the method addOne except the parameter a is transferred as ref type.
  • Line 27-40: return each element of the array as a string.
  • Line 47-48: The array created in the method getArray() is returned and printed.
  • Line 50-58: Call addOne method and output the result of the array. Apparently the content of the array was changed as expected. But the changes in line 15 did not affect the value of b.
  • Line 60-68: This is the same code as that in line 50-58 except calling addOneRef method. This time b was changed to null because of the ref keyword in the argument.

Multidimensional arrays means arrays can be declared with more than one dimension.

Example 01-79-03

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
using System;

class TestMultidimensionalArray
{
    static void Main()
    {
        // Default value of chars
        char[,] c = new char[4,3];
        bool isFound = false;
        for (int i = 0; i < 4; i++){
            for (int j=0; j<3; j++){
                if(c[i, j] != '\0'){
                    isFound = true;
                    break;
                }
            }
        }
        if(isFound){
            Console.WriteLine("The default value of a char is NOT \\0.");
        }
        else
        {
            Console.WriteLine("The default value of a char is \\0.");
        }

        // 3 dimensions array testing
        int[,,] iArray = { { { 1, 2 }, { 3, 4 }, { 5, 6 } }, { { -1, -2 }, { -3, -4 }, { -5, -6 } } };
        for (int i = 0; i < 2; i++)
        {
            for (int j = 0; j < 3; j++)
            {
                for (int k = 0; k < 2; k++)
                {
                    Console.WriteLine("iArray[{0},{1},{2}] = {3}", i, j, k, iArray[i,j,k]);
                }
            }
        }

        Console.Read();
    }
}

Output

The default value of a char is \0.
iArray[0,0,0] = 1
iArray[0,0,1] = 2
iArray[0,1,0] = 3
iArray[0,1,1] = 4
iArray[0,2,0] = 5
iArray[0,2,1] = 6
iArray[1,0,0] = -1
iArray[1,0,1] = -2
iArray[1,1,0] = -3
iArray[1,1,1] = -4
iArray[1,2,0] = -5
iArray[1,2,1] = -6

Explanation

  • Line 8: Declare a 2-dimension char array with 3 rows and 4 columns as below.
  •  Column 0Column 1Column 2Column 3Column 4Column 5
    Row 0c[0, 0]c[0, 1]c[0, 2]c[0, 3]c[0, 4]c[0, 5]
    Row 1c[1, 0]c[1, 1]c[1, 2]c[1, 3]c[1, 4]c[1, 5]
    Row 2c[2, 0]c[2, 1]c[2, 2]c[2, 3]c[2, 4]c[2, 5]
  • Line 9-24: Test if the default value of each char element is \0. As we see the result it is.
  • Line 27: Declare and initialize an integer array with the first dimension 2, the second dimension 3 and the third dimension 2. It can also initialized as follows.
  • int[,,] iArray = new int[,,] { { { 1, 2 }, { 3, 4 }, { 5, 6 } }, { { -1, -2 }, { -3, -4 }, { -5, -6 } } };
    or
    int[,,] iArray = new int[2, 3, 2] { { { 1, 2 }, { 3, 4 }, { 5, 6 } }, { { -1, -2 }, { -3, -4 }, { -5, -6 } } };
    
  • Line 28-37: Output each element of the array.

A jagged array is an array of the arrays and each element of the array can be of different dimensions and size. For example, a jagged array is declared below.

int[][] myArray = new int[4][];

Pay attention, you can not declare a jagged array like a multidimensional array.

int[][] myArray = new int[4][5];	// Jagged array but illegal initialization
int[, ] myArray = new int[4, 5];	// multidimentional array and legal

Each element of the array must be initialized before being used. You can initialize them as follows.

myArray[0] = new int[10];
myArray[1] = new int[4] {1, 10, 100, 1000 };
myArray[2] = new int[] {2, 1, 0, -1, -2 };
myArray[3] = {7, 8, 9, 0 };

Also you can declare a jagged array with multi-dimensions of each element and initialize them in one statement.

int[][,] theJaggedArray = new int[3][,] 
                         {
                            new int[5, 6],
                            new int[3, 2] { {1, 2}, {3, 4}, {5, 6} },	// ilegal using { {1, 2}, {3, 4}, {5, 6} },
                            new int[,] { {11, 22, 33}, {44, 55, 66} } 	// ilegal using { {11, 22, 33}, {44, 55, 66} }
                         };

Example 01-79-04

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
using System;

class TestJaggedArray
{
    static void Main()
    {
        const int SIZE = 5;

        int[][] jaggedArray = new int[SIZE][];
        for (int i = 0; i < SIZE; i++)
        {
            jaggedArray[i] = new int[i + 1];
            Console.Write("jaggedArray[{0}] = {{", i);
            for (int j = 0; j < jaggedArray[i].Length; j++)
            {
                jaggedArray[i][j] = j + 1;
                Console.Write(jaggedArray[i][j]);
                if (j == jaggedArray[i].Length - 1)     // if it is the last element of the array
                {
                    Console.WriteLine(" }");
                }
                else
                {
                    Console.Write(", ");
                }
            }
        }

        Console.Read();
    }
}

Output

jaggedArray[0] = {1 }
jaggedArray[1] = {1, 2 }
jaggedArray[2] = {1, 2, 3 }
jaggedArray[3] = {1, 2, 3, 4 }
jaggedArray[4] = {1, 2, 3, 4, 5 }

Explanation

  • Line 9: Declared a jagged array with 5 element single-dimensional arrays. SIZE is defined as a constant.
  • Line 12: Each element of the jagged array is an array as well and must be initialized before being used.
  • Line 13: To output the curly bracket it must be doubled in Console.Write method.
  • Line 14: jaggedArray[i].Length returns the length of the array jaggedArray[i].
  • Line 16: Assign the value of j + 1 to jaggedArray[i][j].
  • Line 18: Check if it gets to the last element of the array jaggedArray[i]. If it is we'll output closing curly bracket. Otherwise a comma will be printed.

Array class is an abstract class which all the arrays inherit from. You can check the class here for details in Microsoft MSDN. The Length property which was used in previous examples is actually one of the properties of Array class.

Example 01-79-05

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
using System;

class TestArrayClass
{
    public static void OutArray(string arrayName, int[] r){
        Console.Write("{0}: {{", arrayName);
        for (int i = 0; i < r.Length; i++)
        {
            Console.Write(r[i]);
            if (i != r.Length - 1)
            {
                Console.Write(", ");
            }
            
        }
        Console.WriteLine(" }");
    }

    static void Main()
    {
        // Example of Length, LongLength and Rank
        int[] a = { 3, 5, 4, 2, 6, 1 };
        float[,] b = new float[4, 5];
        string[][] c = new string[10][];

        Console.WriteLine("a: Length={0}, LongLength={1}, Rank={2}", a.Length, a.LongLength, a.Rank);
        Console.WriteLine("b: Length={0}, LongLength={1}, Rank={2}", b.Length, b.LongLength, b.Rank);
        Console.WriteLine("c: Length={0}, LongLength={1}, Rank={2}", c.Length, c.LongLength, c.Rank);

        // Clone Method
        int[] d = (int[]) a.Clone();
        int[] e = d;
        Console.WriteLine("After Clone:");
        OutArray("a", a);
        OutArray("d", d);
        OutArray("e", e);
        d[0] = 88;
        Console.WriteLine("After Changing d[0]:");
        OutArray("a", a);
        OutArray("d", d);
        OutArray("e", e);

        // Clear Method
        Array.Clear(d, 1, 3);
        Console.WriteLine("After Clearing d:");
        OutArray("d", d);
        OutArray("e", e);
        Array.Clear(e, 0, e.Length);
        Console.WriteLine("After Clearing e:");
        OutArray("d", d);
        OutArray("e", e);
        OutArray("a", a);

        // Sort and Reverse Method
        Array.Sort(a);
        Console.WriteLine("After Sorting a:");
        OutArray("a", a);
        Array.Reverse(a);
        Console.WriteLine("After Reversing a:");
        OutArray("a", a);

        Console.Read();
    }
}

Output

a: Length=6, LongLength=6, Rank=1
b: Length=20, LongLength=20, Rank=2
c: Length=10, LongLength=10, Rank=1
After Clone:
a: {3, 5, 4, 2, 6, 1 }
d: {3, 5, 4, 2, 6, 1 }
e: {3, 5, 4, 2, 6, 1 }
After Changing d[0]:
a: {3, 5, 4, 2, 6, 1 }
d: {88, 5, 4, 2, 6, 1 }
e: {88, 5, 4, 2, 6, 1 }
After Clearing d:
d: {88, 0, 0, 0, 6, 1 }
e: {88, 0, 0, 0, 6, 1 }
After Clearing e:
d: {0, 0, 0, 0, 0, 0 }
e: {0, 0, 0, 0, 0, 0 }
a: {3, 5, 4, 2, 6, 1 }
After Sorting a:
a: {1, 2, 3, 4, 5, 6 }
After Reversing a:
a: {6, 5, 4, 3, 2, 1 }

Explanation

  • Line 5-17: Define a static method to output the content of an integer array.
  • Line 22-28: Testing the 3 properties. LongLength stands for the whole length of the array. c.LongLength outputs 10 because it is a jagged array with only 10 elements. Rank represents the count of the dimensions of the array.
  • Line 31: Get a clone of a and assign it to d. Casting is needed because a.Clone returns System.Object type.
  • Line 32: Assign d to another array e.
  • Line 33-36: Output the same result.
  • Line 37-41: The first element of d is changed to 88 and output the 3 arrays. As you can see, a was not changed to prove the content of a is copied to d instead of itself. e was changed because arrays are objects with the reference type.
  • Line 44: Clear the element 1, 2, 3 to its default value 0. 1 is the starting index and 3 is the length.
  • Line 48: Clear all the elements of e to 0.
  • Line 55-60: Testing Sort and Reverse method. They are straightforward.