ein Projekt von goloroden.de

Enumerationen

Was sind Enumerationen?

Häufig besteht Bedarf, für einen Parameter einer Methode nur eine gewisse Auswahl an vorgegebenen Werten zuzulassen. Handelt es sich dabei nur um einen Wahrheitswert, also einen Wert, der entweder wahr oder falsch ist, bietet sich dafür als Typ bool an. Dieser Typ sollte allerdings nur verwendet werden, wenn true und false tatsächlich die beiden Alternativen darstellen.

In der Praxis wird bool häufig auch dann verwendet, wenn nur eine der beiden Alternativen selbstbeschreibend ist. Der Konstruktor der Klasse ComplexNumber könnte beispielsweise derart erweitert werden, dass ihm ein Parameter vom Typ bool übergeben wird, der angibt, ob es sich bei der zu initialisierenden komplexen Zahl um eine konjugierte Zahl handelt. In diesem Fall entsprechen die möglichen Werte true und false den beiden Alternativen, da eine komplexe Zahl entweder konjugiert ist oder nicht.

In einem anderen Fall könnte die Schnittstelle IPersistent um einen Parameter erweitert werden, der angibt, ob die Daten auf Festplatte geschrieben und von dort wieder geladen werden sollen. Hierfür ergibt der Typ bool wenig Sinn, denn true gibt als Wert zwar an, dass die Festplatte verwendet werden soll, aber die Angabe von false ist sinnlos - es wird zwar festgelegt, dass die Festplatte nicht verwendet werden soll, die Angabe des Speicherortes ist aber nicht gegeben.

Für diese Fälle, in denen mehr als eine Option angegeben werden sollen, verfügt C# über sogenannte Enumerationen. Eine Enumeration kann verschiedene Werte enthalten, die über ihren jeweiligen Namen angesprochen werden können. Definiert wird eine Enumeration mit Hilfe des Schlüsselwortes enum, wobei die einzelnen Werte kommasepariert innerhalb geschweifter Klammern aufgezählt werden. Im Gegensatz zu einer Klasse muss allerdings hinter der schließenden geschweiften Klammer ein Semikolon angegeben werden.

Die Namenskonventionen für Enumerationen entsprechen prinzipiell denen von Klassen, allerdings wird der Name einer Enumeration im Plural angegeben.
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>
    /// Contains storage locations for the persistence interface.
    /// </summary>
    public enum StorageLocations
    {
        /// <summary>
        /// The disk as storage location.
        /// </summary>
        Disk,

        /// <summary>
        /// A databse as storage location.
        /// </summary>
        Database
    };
}
Der Vorteil in der Verwendung einer Enumeration an Stelle einer Zahl oder einer Zeichenkette zur Identifikation des Wertes liegt zum einen in der Verständlichkeit, da der entsprechende Wert über seinen Namen angesprochen wird, zum anderen in der Überprüfbarkeit durch den Compiler. Ein Schreibfehler eines Wertes aus einer Enumeration wird vom Compiler entdeckt, während ein Schreibfehler in einer Zeichenkette erst zur Laufzeit durch einen auftretenden Fehler entdeckt wird.

Intern wird eine Enumeration allerdings durch den Datentyp int repräsentiert, wobei die einzelnen Werte der Enumeration von Null beginnend nummeriert werden. Dieses standardmäßige Verhalten kann allerdings überschrieben werden, indem einem oder mehreren Werten explizit eine Ganzzahl zugeordnet wird. Alle Werte, denen keine eigene Zahl zugeordnet wird, erhalten dabei als interne Repräsentation eine automatisch inkrementierte Nummer.

Im folgenden Beispiel beginnt die Enumeration bei eins, da für den Wert Database keine eigene Repräsentation angegeben wird, erhält er automatisch den nächsthöheren Wert, nämlich zwei.
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>
    /// Contains storage locations for the persistence interface.
    /// </summary>
    public enum StorageLocations
    {
        /// <summary>
        /// The disk as storage location.
        /// </summary>
        Disk = 1,

        /// <summary>
        /// A databse as storage location.
        /// </summary>
        Database
    };
}
Anders als Klassen leiten Enumerationen nicht direkt von dem Typ object ab, sondern von der Struktur Enum im Namensraum System.