Umwandlung und Typkonvertierungen (C#-Programmierhandbuch)

Weil C# zur Kompilierzeit statisch typisiert ist, kann eine Variable, nachdem sie deklariert wurde, nicht erneut deklariert werden oder einen Wert von einem anderen Typ zugewiesen bekommen, es sei denn, dieser Typ ist implizit in den Typ der Variable konvertierbar. string kann beispielsweise nicht implizit in int konvertiert werden. Deshalb können Sie, nachdem Sie i als int deklariert haben, nicht die Zeichenfolge „Hello“ zuweisen. Dies wird im folgenden Beispiel veranschaulicht:

int i;

// error CS0029: can't implicitly convert type 'string' to 'int'
i = "Hello";

Manchmal müssen Sie möglicherweise einen Wert in eine Variable oder einen Methodenparameter eines anderen Typen kopieren. Sie haben z.B. möglicherweise eine Ganzzahlvariable, die Sie an eine Methode übergeben müssen, deren Parameter vom Type double ist. Möglicherweise müssen Sie auch einer Variablen eines Schnittstellentyps eine Klassenvariable zuweisen. Derartige Vorgänge werden als Typkonvertierungen bezeichnet. In C# können Sie folgende Arten von Konvertierungen durchführen:

  • Implizite Konvertierungen: Es ist keine besondere Syntax erforderlich, da die Konvertierung immer erfolgreich ist und keine Daten verloren gehen. Beispiele sind Konvertierungen von kleinere in größere Ganzzahltypen und Konvertierungen von abgeleiteten in Basisklassen.

  • Explizite Konvertierungen (Umwandlungen) : Für explizite Konvertierungen ist ein Cast-Ausdruck erforderlich. Eine Umwandlung ist erforderlich, wenn Informationen bei einer Konvertierung verloren gehen können oder wenn die Konvertierung aus anderen Gründen fehlschlagen könnte. Häufig auftretende Beispiele sind u.a. numerische Konvertierungen in einen Typen, der eine geringere Genauigkeit oder einen kleineren Bereich aufweist, oder Konvertierungen einer Instanz einer Basisklasse in eine abgeleitete Klasse.

  • Benutzerdefinierte Konvertierungen: Benutzerdefinierte Konvertierungen verwenden spezielle Methoden, die Sie definieren können, um explizite und implizite Konvertierungen zwischen benutzerdefinierten Typen zu ermöglichen, die nicht in einem Verhältnis „Basisklasse – abgeleitete Klasse“ zueinander stehen. Weitere Informationen finden Sie unter Benutzerdefinierte Konvertierungsoperatoren.

  • Konvertierungen mit Hilfsklassen: Für eine Konvertierung von nicht kompatiblen Typen, z.B. von ganzen Zahlen und System.DateTime-Objekten, oder von Hexadezimalzeichenfolgen und Bytearrays können Sie die System.BitConverter-Klasse, die System.Convert-Klasse und die Parse-Methoden der integrierten numerischen Typen (z.B. Int32.Parse) verwenden. Weitere Informationen finden Sie unter Vorgehensweise: Konvertieren eines Bytearrays in einen ganzzahligen Typ, Vorgehensweise: Konvertieren einer Zeichenfolge in eine Zahl und Vorgehensweise: Konvertieren zwischen Hexadezimalzeichenfolgen und numerischen Typen.

Implizite Konvertierungen

Eine implizite Konvertierung kann für integrierte numerische Typen durchgeführt werden, wenn der zu speichernde Wert in die Variable passt, ohne abgeschnitten oder abgerundet zu werden. Für integrale Typen bedeutet dies, dass der Bereich des Quelltyps eine korrekte Teilmenge des Bereichs für den Zieltyp ist. Zum Beispiel kann eine Variable vom Typ long (64-Bit-Integer) jeden Wert speichern, den eine Variable vom Typ int (32-Bit-Integer) speichern kann. Im folgenden Beispiel konvertiert der Compiler den Wert von num auf der rechten Seite implizit in einen long-Typ, bevor er ihn bigNum zuweist.

// Implicit conversion. A long can
// hold any value an int can hold, and more!
int num = 2147483647;
long bigNum = num;

Eine vollständige Liste aller impliziten numerischen Konvertierungen finden Sie unter Implizite numerische Konvertierungen im Artikel Integrierte numerische Konvertierungen (C#-Referenz).

Eine implizite Konvertierungen für Verweistypen von einer Klasse in jede ihrer direkten oder indirekten Basisklassen oder Schnittstellen ist immer möglich. Es ist keine spezielle Syntax erforderlich, da eine abgeleitete Klasse immer alle Member der Basisklasse enthält.

Derived d = new Derived();

// Always OK.
Base b = d;

Explizite Konvertierungen

Wenn allerdings eine Konvertierung nicht ohne möglichen Informationsverlust durchgeführt werden kann, fordert der Compiler eine explizite Konvertierung; diese wird als Umwandlung bezeichnet. Eine Umwandlung bietet die Möglichkeit, den Compiler explizit zu informieren, dass Sie eine Konvertierung vornehmen möchten, und dass Ihnen bewusst ist, dass dies einen Datenverlust oder einen Fehler zur Laufzeit zur Folge haben kann. Wenn Sie eine Umwandlung durchführen möchten, geben Sie den Typ, in den umgewandelt werden soll, in Klammern am Anfang des zu konvertierenden Wertes oder der zu konvertierenden Variablen an. Das folgende Programm wandelt ein double in ein int um. Das Programm führt ohne die Umwandlung keine Kompilierung durch.

class Test
{
    static void Main()
    {
        double x = 1234.7;
        int a;
        // Cast double to int.
        a = (int)x;
        System.Console.WriteLine(a);
    }
}
// Output: 1234

Eine vollständige Liste der expliziten numerischen Konvertierungen finden Sie unter Explicit numeric conversions (Explizite numerische Konvertierungen) im Artikel Built-in numeric conversions (Integrierte numerische Konvertierungen).

Eine explizite Umwandlung ist für Verweistypen erforderlich, wenn Sie von einer Basisklasse in eine abgeleitete Klasse konvertieren möchten:

// Create a new derived type.
Giraffe g = new Giraffe();

// Implicit conversion to base type is safe.
Animal a = g;

// Explicit conversion is required to cast back
// to derived type. Note: This will compile but will
// throw an exception at run time if the right-side
// object is not in fact a Giraffe.
Giraffe g2 = (Giraffe)a;

Ein Umwandlungsvorgang zwischen Verweistypen ändert nicht den Laufzeittypen des zugrunde liegenden Objekts; er ändert lediglich den Typ des Wertes, der als Verweis auf das Objekt verwendet wird. Weitere Informationen finden Sie unter Polymorphie.

Typkonvertierungsausnahmen zur Laufzeit

In manchen Verweistypkonvertierungen kann der Compiler nicht bestimmen, ob eine Umwandlung zulässig ist. Es ist möglich, dass ein Umwandlungsvorgang, der ordnungsgemäß kompiliert, zur Laufzeit fehlschlägt. Eine fehlgeschlagene Typumwandlung zur Laufzeit löst wie in folgendem Beispiel dargestellt eine InvalidCastException aus.

class Animal
{
    public void Eat() => System.Console.WriteLine("Eating.");

    public override string ToString() => "I am an animal.";
}

class Reptile : Animal { }
class Mammal : Animal { }

class UnSafeCast
{
    static void Main()
    {
        Test(new Mammal());

        // Keep the console window open in debug mode.
        System.Console.WriteLine("Press any key to exit.");
        System.Console.ReadKey();
    }

    static void Test(Animal a)
    {
        // System.InvalidCastException at run time
        // Unable to cast object of type 'Mammal' to type 'Reptile'
        Reptile r = (Reptile)a;
    }
}

Die Methode Test verfügt über einen Parameter Animal, sodass es eine gefährliche Annahme ist, das Argument a explizit in ein Reptile-Element umzuwandeln. Es ist sicherer, keine Annahmen zu verwenden, sondern stattdessen den Typ zu überprüfen. C# stellt den is-Operator bereit, sodass Sie die Kompatibilität prüfen können, bevor Sie die Umwandlung tatsächlich ausführen. Weitere Informationen finden Sie unter Vorgehensweise: Sicheres Umwandeln mit Musterabgleich und den Operatoren „as“ und „is“.

C#-Sprachspezifikation

Weitere Informationen finden Sie im Abschnitt Konvertierungen der C#-Sprachspezifikation.

Weitere Informationen