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);
|
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]);
}
}
}
|