Testseite: Unterschied zwischen den Versionen

Aus Das Sopra Wiki
Keine Bearbeitungszusammenfassung
Keine Bearbeitungszusammenfassung
Zeile 31: Zeile 31:


                 Horse [
                 Horse [
                         label = "{Horse||+ mooh() : void\l+kick (): bool\l}"
                         label = "{Horse||+ mooh() : void\l+ kick (): bool\l}"
                 ]
                 ]



Version vom 12. November 2009, 19:03 Uhr

Casten[1] bezeichnet das Umwandeln eines Typs in einen anderen Typ[2]. Gängige Beispiele sind zum Beispiel Genauigkeitsumwandlungen bei Zahlen

int i = 15;
double l = (double)i;
int j = (int i);

Das (double) im ersten Cast kann man dabei weglassen, da keine Genauigkeit verloren geht.

Man bezeichnet auch das Umwandeln einer Instanz einer Klasse in eine Instanz einer ihrer Subklasse. Angenommen, wir haben folgende Klassenhirarchie: <graphviz> digraph GX {

       fontname = "Bitstream Vera Sans"
       fontsize = 8
       node [
               fontname = "Bitstream Vera Sans"
               fontsize = 8
               shape = "record"
       ]
       edge [
               fontname = "Bitstream Vera Sans"
               fontsize = 8
       ]
       Animal [
               label = "{Animal|+ name : string\l+ age : int\l|+ die() : void\l}"
       ]


               Horse [
                       label = "{Horse||+ mooh() : void\l+ kick (): bool\l}"
               ]
               Cat [
                       label = "{Cat||+ meow() : void\l}"
               ]
       edge [
               arrowhead = "empty"
       ]
       Horse -> Animal
       Cat -> Animal
       edge [
               arrowhead = "none"
               headlabel = "0..*"
               taillabel = "0..*"
       ]

} </graphviz>

Dann können wir folgendes machen:

Animal a1 = new Dog();
Animal a2 = new Cat();

Wenn wir jetzt mit Reflection nach dem Typ fragen

a1.GetType().ToString(); //gibt "Dog" zurück
a2.GetType().ToString(); //gibt "Cat" zurück

Da der Compiler keine automatischen Casts zulässt müssen wir das von Hand machten:

Dog dog = (Dog)a1;
Cat cat = (Cat)a2;

Dabei muss man beachten, daß man auch ungültige Casts machen kann. Wenn man a1 nach Cat umwandeln möchte, wird es zur Laufzeit eine InvalidCastException werfen. Dies ist teilweise schwer zu reproduzieren.

Als Abhilfe stellt C# einige Konstrukte zur Verfügung.

Dog dog = a1 as Dog;
Dog cat = a1 as Dog;
Console.WriteLine((dog == null)); // gibt "false" aus
Console.WriteLine((cat == null)); // gibt "true" aus

Hier wird bei einem ungültigen Cast das Zielobjekt auf null gesetzt.

Alternativ kann man auch einen Typvergleich machen

Console.WriteLine((a1 is Cat)); // gibt "false" aus
Console.WriteLine((a2 is Cat)); // gibt "true" aus

Man sollte is[3] nicht benutzen um auf einen möglichen Cast zu prüfen. as[4] ist hier vorzuziehen da .NET sonst zweimal einen Cast ausführt (eimal beim is und einmal beim zuweisen). Beim as kann man dagegen relativ günstig auf null prüfen.

Referenzen