myCSharp.de - DIE C# und .NET Community
Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 
 | Suche | FAQ

» Hauptmenü
myCSharp.de
» Startseite
» Forum
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Suche
» Regeln
» Wie poste ich richtig?
» Forum-FAQ

Mitglieder
» Liste / Suche
» Wer ist wo online?

Ressourcen
» openbook: Visual C#
» openbook: OO
» Microsoft Docs

Team
» Kontakt
» Übersicht
» Wir über uns

» myCSharp.de Diskussionsforum
Du befindest Dich hier: Community-Index » Diskussionsforum » Entwicklung » Grundlagen von C# » Casting von Klassenobjekten???
Letzter Beitrag | Erster ungelesener Beitrag Druckvorschau | Thema zu Favoriten hinzufügen

Antwort erstellen
Zum Ende der Seite springen  

Casting von Klassenobjekten???

 
Autor
Beitrag « Vorheriges Thema | Nächstes Thema »
CompilerSaysNo CompilerSaysNo ist männlich
myCSharp.de-Mitglied

Dabei seit: 11.05.2020
Beiträge: 7
Entwicklungsumgebung: Visual Studio 2019


CompilerSaysNo ist offline

Casting von Klassenobjekten???

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo liebe Community,

ich schlage mich nun bereits seit einiger Zeit mit einer Frage zum Thema "Casten von Klassenobjekten" rum und komm nicht dahinter. Ich hoffe ihr könnt mich erhellen. :-)

Ich habe zwei einfache Beispielklassen:

C#-Code:
        class A
        {
            public int Zähler { get; protected set; }

            public virtual void ErhöheZähler()
            {
                Zähler++;
            }
        }

        class B : A
        {
            public override void ErhöheZähler()
            {
                Zähler += 5;
            }

            public void Essen()
            {

            }
        }

Nun zu meinem Gehirnknoten:

C#-Code:
            A objekt1 = new A();
            A objekt2 = new B();
            **B objekt3 = objekt2;**

            objekt1.ErhöeZähler();
            objekt2.ErhöheZähler();

Den implizierten Cast in Zeile 3 will der Compiler nicht machen. Die Erklärungen, die ich bisher dazu gefunden haben lauten alle mehr oder weniger:

"Der Compiler kann hier nicht entscheiden vom welchem Typ das Objekt hinter "objekt2" ist, da es mehrere Klassen geben kann, die von A ableiten könnten und kann somit den implizierten Cast nicht durchführen."

Ok klingt soweit logisch, auch wenn es hier nur eine Subklasse gibt, aber es könnte ja noch weitere geben. Und das kann der Compiler nicht erkennen???


In Zeile 6 rufe ich nun allerdings über die API von "A" die Methode "ErhöheZähler()" auf und der Compiler erkennt direkt, dass dahinter ein Objekt des Typs B liegt und "leitet" direkt zur override-Methode von Class B um.

Warum erkennt der Compiler dann nicht auch in Zeile 3, dass hier ein Objekt von Typ B hinterliegt???

In Zeile 6 scheint der Compiler zu erkennen, dass dort ein Objekt vom Typ B hinterliegt und in Zeile 3 wieder nicht??


Ich finde auch keine Erklärungen, die dies aufklären, sondern alles was ich an Erklärungen finde geht immer so in die Richtung wie oben gennannt.

Das lässt mir einfach keine Ruhe und bremst mich in meinem weiteren Fortschritt. Denn ich bin so, dass ich immer verstehen MUSS "Warum" etwas so ist und nicht nur das es so ist. So bin ich halt und dann macht mich sowas wahnsinnig.

Ich hoffe ihr könnt mich erleuchten.



Gruß
Maik

Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von CompilerSaysNo am 04.06.2020 15:52.

Neuer Beitrag 04.06.2020 15:50 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
FZelle
myCSharp.de-Poweruser/ Experte

Dabei seit: 23.04.2004
Beiträge: 9.859


FZelle ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Es ist simple zu erklären.

Wenn du eine Variable A erzeugst ( A object2 ) dann steht eben A für alles was A kann und nicht für alle klassen die von A ableiten.

Da Du ErhöheZähler virtual declariert hast, wird schon die richtige funktion ausgeführt.
Neuer Beitrag 04.06.2020 16:05 Beiträge des Benutzers | zu Buddylist hinzufügen
T-Virus T-Virus ist männlich
myCSharp.de-Mitglied

Dabei seit: 17.04.2008
Beiträge: 1.641
Entwicklungsumgebung: Visual Studio, Codeblocks, Edi
Herkunft: Nordhausen, Nörten-Hardenberg


T-Virus ist offline Füge T-Virus Deiner Kontaktliste hinzu

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Die Konvertierung in Zeile 3 kannst du eigentlich nur durch hartes Boxing forcieren.
Sollte man i.d.R. eigentlich vermeiden und ist auch nur nötig wenn der tatsächliche Typ explizit gefordert wäre.
Die Runtime merkt sich, dass objekt2 eigentlich von Typ B ist und ruft dann auch entsprechend die Methode von Typ B auf.
An der Stelle muss man aber dem Compiler, der dies nicht direkt erkennt, dies eben durch explizite Typenumwandlung (Boxing) mitteilen.

C#-Code:
A objekt1 = new A();
A objekt2 = new B();
B objekt3 = (B)objekt2;

In Zeile 6 erkennt nicht der Compiler, dass es ein Objekt B ist sondern die Runtime von .NET merkt dies.
Hier wird erst zur Laufzeit sich der Typ gemerkt und die richtige Methode von Typ B aufgerufen.
Hier must du zwischen Compiler und Laufzeit immer unterscheiden.
Der Compiler sieht nur den Syntax und will daraus die Anwendung kompilieren.
Die Laufzeit hingegen muss solche Typen Informationen aber kennen und merken.

Ist als Einsteiger noch recht schwierig es zu verstehen, lernt man aber mit der Zeit.
Im besten Fall sollte man von einer expliziten Konvertierung auch nur in den nötigsten Fällen gebrauch machen müssen.
Es ist immer besser, wenn du wie bei Zeile 2 dann gegen die Basis Programmierst.
Im Bestfall handelt es sich dann um ein Interface, dass deine Klasse implementiert.
Dadurch ist dein Code auch austauschbar bzw. kannst du mit unterschiedlichen Implementierungen gegen deinen Code arbeiten.

T-Virus
Neuer Beitrag 04.06.2020 16:14 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
witte
myCSharp.de-Mitglied

Dabei seit: 03.09.2010
Beiträge: 923


witte ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Zitat von T-Virus:
Die Konvertierung in Zeile 3 kannst du eigentlich nur durch hartes Boxing forcieren.

Boxing ist der Prozess der Konvertierung eines Wertetypes in object damit der Wert in der Heap gespeichert werden kann. Es ist nicht böse gemeint - aber sei bitte nicht so lax, du verwirrst den Fragesteller damit mehr als dass Du ihm hilfst.
Neuer Beitrag 04.06.2020 16:25 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
CompilerSaysNo CompilerSaysNo ist männlich
myCSharp.de-Mitglied

Dabei seit: 11.05.2020
Beiträge: 7
Entwicklungsumgebung: Visual Studio 2019

Themenstarter Thema begonnen von CompilerSaysNo

CompilerSaysNo ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Zitat von T-Virus:
Hier must du zwischen Compiler und Laufzeit immer unterscheiden.

Ich denke dies ist der entscheidende Hinweis. Dann muss ich mich dringend nochmal genauer mit diesen beiden Elementen befassen. Wenn du dazu gute Quellen hast, dann würde ich mich freuen, ansonsten finde ich da sicher auch selbst etwas.

Es kann so einfach sein, aber wenn einem das entscheidende Puzzlestück fehlt, dann hängt man erbarmungslos fest.^^

Vielen Dank.

Gruß
Maik
Neuer Beitrag 04.06.2020 16:27 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
CompilerSaysNo CompilerSaysNo ist männlich
myCSharp.de-Mitglied

Dabei seit: 11.05.2020
Beiträge: 7
Entwicklungsumgebung: Visual Studio 2019

Themenstarter Thema begonnen von CompilerSaysNo

CompilerSaysNo ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Zitat von witte:
Boxing ist der Prozess der Konvertierung eines Wertetypes in object damit der Wert in der Heap gespeichert werden kann.

.

Ich habe vermutet, dass damit ein expliziter Cast gemeint ist. Sollte dies nicht so sein, dann bin ich über das Thema Boxing wohl noch nicht gestolpert...
Neuer Beitrag 04.06.2020 16:30 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
T-Virus T-Virus ist männlich
myCSharp.de-Mitglied

Dabei seit: 17.04.2008
Beiträge: 1.641
Entwicklungsumgebung: Visual Studio, Codeblocks, Edi
Herkunft: Nordhausen, Nörten-Hardenberg


T-Virus ist offline Füge T-Virus Deiner Kontaktliste hinzu

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

@witte
Hast recht, explizite Konvertierung ist hier der richtige Begriff.
Mein Fehler!

@CompilerSaysNo
Du musst, wie in dem Code Beispiel, den Typen hier explizit konvertieren.
Boxing war hier der falsche Begriff von meiner Seite aus.

T-Virus

Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von T-Virus am 04.06.2020 16:48.

Neuer Beitrag 04.06.2020 16:47 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
witte
myCSharp.de-Mitglied

Dabei seit: 03.09.2010
Beiträge: 923


witte ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

@CompilerSaysNo: Wenn Du viel Zeit hast kannst du dir mal das OO-Buch anschauen welches hier unter Ressourcen verlinkt ist. Der Link zeigt auf eine lesbare Online-Version. Da wird das m.E. sehr gut erklärt - z.B. unter dynamischer Polymorphie. Musst mal schauen ob dir das liegt.

Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von witte am 05.06.2020 10:25.

Neuer Beitrag 04.06.2020 16:56 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Baumstruktur | Brettstruktur       | Top 
myCSharp.de | Forum Der Startbeitrag ist älter als 4 Monate.
Der letzte Beitrag ist älter als 4 Monate.
Antwort erstellen


© Copyright 2003-2020 myCSharp.de-Team | Impressum | Datenschutz | Alle Rechte vorbehalten. | Dieses Portal verwendet zum korrekten Betrieb Cookies. 30.10.2020 19:31