ein Projekt von goloroden.de

Arrays

Was sind Arrays?

Felder ermöglichen zwar das Speichern von Daten, aber ein Feld kann jeweils nur einen einzelnen Wert aufnehmen. Besteht die Notwendigkeit, mehrere gleichartige Werte speichern zu müssen, so müssen mehrere Felder definiert werden. Insbesondere bei einer hohen Anzahl an Werten neigt dieses Verfahren aber dazu, unübersichtlich zu werden. Außerdem sind Fälle denkbar, in denen nicht bereits zur Entwicklungszeit bekannt ist, wie viele Werte gespeichert werden sollen, da sich dies erst zur Laufzeit ergibt.

Die Lösung für dieses Problem stellen sogenannte Arrays dar, die mehrere Werte eines Typs aufnehmen können. Anstatt also jeden Wert in einem eigenen Feld zu speichern, wird statt dessen ein Array als Feld angelegt, dessen Dimension ausreichend ist, um alle Werte aufzunehmen.

Der Typ eines Arrays besteht aus dem Typ der Daten, die das Array aufnehmen soll, dem ein Paar eckige Klammern folgen. Da ein Array ein Verweistyp ist, wird es ebenso wie ein Objekt mit Hilfe des Schlüsselwortes new erzeugt, wobei dort innerhalb eckiger Klammern die Größe des Arrays definiert wird. Im Gegensatz zu den übrigen Klassen leitet ein Array allerdings nicht direkt von object ab, sondern von der Klasse System.Array.
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
using System;

namespace GoloRoden.GuideToCSharp
{
    /// <summary>
    /// Represents the application class.
    /// </summary>
    public class Program
    {
        /// <summary>
        /// Executes the application.
        /// </summary>
        public static void Main()
        {
            // Define an array for fibonacci numbers.
            int[] fibonacci = new int[10];
        }
    }
}
Auf die einzelnen Elemente des Arrays kann im weiteren Verlauf der Anwendung wiederum mit Hilfe der eckigen Klammern zugegriffen werden, indem in ihnen der Index des Elements angegeben wird, auf das zugegriffen werden soll. In C# beginnen Indizes von Arrays immer bei Null, das heißt, der höchste Index in einem Array mit n Elementen trägt die Nummer n-1.
C#
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;

namespace GoloRoden.GuideToCSharp
{
    /// <summary>
    /// Represents the application class.
    /// </summary>
    public class Program
    {
        /// <summary>
        /// Executes the application.
        /// </summary>
        public static void Main()
        {
            // Define an array for fibonacci numbers.
            int[] fibonacci = new int[10];

            // Initialize the array with the first two
            // numbers.
            fibonacci[0] = 1;
            fibonacci[1] = 1;

            // Calculate all following numbers.
            for(int i = 2; i < 10; i++)
            {
                fibonacci[i] =
                    fibonacci[i - 1] + fibonacci[i - 2];
            }
        }
    }
}
Da es aufwändig und unübersichtlich sein kann, Arrays auf diese Art zu initialiseren, können die enthaltenen Werte auch direkt innerhalb geschweifter Klammern angegeben werden. In diesem Fall entfällt die Angabe der Größe des Arrays, sie wird statt dessen aus der Anzahl der übergebenen Werte ermittelt.
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
using System;

namespace GoloRoden.GuideToCSharp
{
    /// <summary>
    /// Represents the application class.
    /// </summary>
    public class Program
    {
        /// <summary>
        /// Executes the application.
        /// </summary>
        public static void Main()
        {
            // Define an array for fibonacci numbers and
            // fill it with  numbers.
            int[] fibonacci =
                new int[] { 1, 1, 2, 3, 5, 8, 13, 21, 34, 55 };
        }
    }
}
Arrays, die wie die bisherigen Beispiele einer Aufzählung von Werten entsprechen, werden auch als eindimensionale Arrays bezeichnet, da ihre Elemente nur über einen Index verfügen. In C# können Arrays jedoch auch mehrdimensional definiert werden, so dass beispielsweise bei zwei Dimensionen eine Tabelle und bei dreien ein Würfel von Daten entsteht.

Um ein Array mit mehreren Indizes auszustatten, genügt es, bei seiner Definition mehrere Größen anzugeben, die jeweils durch ein Komma voneinander getrennt werden. Hierbei muss allerdings beachtet werden, dass die Kommata innerhalb der eckigen Klammern der Typdefinition ebenfalls angegeben werden müssen. Im folgenden Beispiel wird ein Schachbrett als Feld von acht mal acht Feldern definiert, auf dem Figuren platziert werden können.
C#
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
using System;

namespace GoloRoden.GuideToCSharp
{
    /// <summary>
    /// Contains chess figures.
    /// </summary>
    public enum ChessFigure
    {
        /// <summary>
        /// The figure castle.
        /// </summary>
        Castle,

        /// <summary>
        /// The figure knight.
        /// </summary>
        Knight

        // TODO gr: Define the other chess figures.
        //          2008-01-03
    }

    /// <summary>
    /// Represents the application class.
    /// </summary>
    public class Program
    {
        /// <summary>
        /// Executes the application.
        /// </summary>
        public static void Main()
        {
            // Create a chess board.
            ChessFigure[,] chessBoard =
                new ChessFigure[8, 8];

            // Put chessmen onto the board.
            chessBoard[0, 0] = ChessFigure.Castle;
            chessBoard[0, 1] = ChessFigure.Knight;
        }
    }
}
Neben der Möglichkeit, Arrays ein- oder mehrdimensional zu definieren, besteht zusätzlich die Option, Arrays ineinander zu verschachteln. Prinzipiell entspricht ein verschachteltes Array einem mehrdimensionalen Array, allerdings können verschachtelte Arrays beispielsweise für jede einzelne Zeile eine individuelle Anzahl an Spalten definieren.
C#
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
using System;

namespace GoloRoden.GuideToCSharp
{
    /// <summary>
    /// Represents the application class.
    /// </summary>
    public class Program
    {
        /// <summary>
        /// Executes the application.
        /// </summary>
        public static void Main()
        {
            // Create a nested array with two lines and
            // three columns in the first row and two
            // columns in the second row.
            string[] colors = new string[2];
            colors[0] = new string[3];
            colors[1] = new string[2];

            // Fill the array.
            colors[0][0] = "Blau";
            colors[0][1] = "Blue";
            colors[0][2] = "Bleu";
            colors[1][0] = "Rot";
            colors[1][1] = "Red";
        }
    }
}
Bei verschachtelten Arrays ist zu beachten, dass die einzelnen Dimensionen in jeweils einem eigenen Paar eckiger Klammern angegeben werden, und die Dimensionen nicht wie bei den mehrdimensionalen Arrays kommasepariert sind.

Der Einsatz von Arrays ermöglicht nicht nur, mehrere Werte in einer einzelnen Variablen beziehungsweise einem Feld zu speichern, sondern auch, Parameter von der Kommandozeile an die Methode Main zu übergeben. Als Parameter kann für diese in C# nämlich ein Array von Strings angegeben werden, das die einzelnen auf der Kommandozeile angegebenen Parameter enthält.

Auf die einzelnen Elemente kann analog zu den Elementen aller anderen Arrays mit Hilfe des Indizes zugegriffen werden.
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
using System;

namespace GoloRoden.GuideToCSharp
{
    /// <summary>
    /// Represents the application class.
    /// </summary>
    public class Program
    {
        /// <summary>
        /// Executes the application.
        /// </summary>
        /// <param name="arguments">The arguments.</param>
        public static void Main(string[] arguments)
        {
            Console.WriteLine(
                "The first argument is " + arguments[0]);
        }
    }
}
Arrays können außerdem dazu eingesetzt werden, eine vorher nicht festgelegte Anzahl von Parametern an eine Methode zu übergeben, indem die Werte in ein Array verpackt werden, und nur dieses Array übergeben wird. Da der Typ des Arrays nicht die Größenangabe enthält, kann das übergebene Array eine beliebige Größe haben.

Allerdings kann es aufwändig sein, zur Übergabe einiger Parameter ein Array erzeugen zu müssen. Daher stellt C# das Schlüsselwort params zur Verfügung, mit dem ein Array alternativ auch als Liste einzelner Werte übergeben werden kann. Sofern das Schlüsselwort params einem Parameter vorangestellt wird, muss dieser Parameter zum einen ein Array sein, zum zweiten dürfen ihm keine weiteren Parameter folgen, und er muss der einzige Parameter sein, der über das params-Schlüsselwort verfügt.
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
using System;

namespace GoloRoden.GuideToCSharp
{
    /// <summary>
    /// Represents a foo class.
    /// </summary>
    public class Foo
    {
        /// <summary>
        /// Sorts the specified numbers.
        /// </summary>
        /// <param name="numbers">An array of
        /// numbers.</param>
        /// <returns>A sorted array of the specified
        /// numbers.</returns>
        public int[] Sort(params int[] numbers)
        {
            // TODO gr: Sort the numbers and return them
            //          as int array to the caller.
            //          2008-01-03
        }
    }
}
Wird eine solche Methode aufgerufen, so kann ihr an Stelle eines Arrays
C#
1
this.Sort(new int[] { 3, 13, 1, 8, 1, 5, 2, 34, 21, 55 });
auch eine Auflistung einzelner Zahlen übergeben werden.
C#
1
this.Sort(3, 13, 1, 8, 1, 5, 2, 34, 21, 55);

Indexer

Verwandt mit Arrays sind die sogenannten Indexer, die den indizierten Zugriff auf eine Klasse ermöglichen. Sie entsprechen technisch gesehen einer Eigenschaft, die allerdings immer den Namen this trägt und der als Parameter ein Index innerhalb eckiger Klammern übergeben wird.

Auf diesen kann dann innerhalb der Methoden get und set zugegriffen werden, um beispielsweise gezielt auf ein bestimmtes Element eines Arrays zuzugreifen.
C#
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
using System;

namespace GoloRoden.GuideToCSharp
{
    /// <summary>
    /// Represents an IP address.
    /// </summary>
    public class IPAddress
    {
        /// <summary>
        /// Contains the individual parts of an IP address.
        /// </summary>
        private int[] _ipPart;

        /// <summary>
        /// Gets or sets an individual part of the IP
        /// address.
        /// </summary>
        /// <param name="i">The index of the individual
        /// part.</param>
        /// <returns>The individual part of the IP
        /// address.</returns>
        public int this[int i]
        {
            get
            {
                return this._ipPart[i];
            }

            set
            {
                this._ipPart[i] = value;
            }
        }

        /// <summary>
        /// Initializes a new instance of the IPAddress
        /// type.
        /// </summary>
        public IPAddress()
        {
            this._ipPart = new int[4];
        }

        /// <summary>
        /// Initializes a new instance of the IPAddress
        /// type.
        /// </summary>
        /// <param name="ipPart1">The first part of the IP
        /// address.</param>
        /// <param name="ipPart2">The second part of the IP
        /// address.</param>
        /// <param name="ipPart3">The thired part of the IP
        /// address.</param>
        /// <param name="ipPart4">The fourth part of the IP
        /// address.</param>
        public IPAddress(int ipPart1, int ipPart2, int ipPart3, int ipPart4)
            : this()
        {
            // Set the individual parts.
            this._ipPart[0] = ipPart1;
            this._ipPart[1] = ipPart2;
            this._ipPart[2] = ipPart3;
            this._ipPart[3] = ipPart4;
        }
    }
}
Um diesen Indexer nun von außen zu verwenden, muss die Eigenschaft nicht mehr explizit angegeben werden, sondern es genügt, die eckigen Klammern direkt hinter dem Namen des Objekts anzugeben.
C#
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
using System;

namespace GoloRoden.GuideToCSharp
{
    /// <summary>
    /// Represents the application class.
    /// </summary>
    public class Program
    {
        /// <summary>
        /// Executes the application.
        /// </summary>
        public static void Main()
        {
            // Create a new instance of the IP address and
            // initialize it to 192.168.0.1.
            IPAddress ipAddress =
                new IPAddress(192, 168, 0, 1);

            // Print the first part of the address to the
            // console.
            Console.WriteLine(ipAddress[0]);
        }
    }
}