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# » Lebensdauer von Objekten; Werden Subklassen nicht mit zerstört?
Letzter Beitrag | Erster ungelesener Beitrag Druckvorschau | Thema zu Favoriten hinzufügen

Antwort erstellen
Zum Ende der Seite springen  

Lebensdauer von Objekten; Werden Subklassen nicht mit zerstört?

 
Autor
Beitrag « Vorheriges Thema | Nächstes Thema »
CrocodileDundee
myCSharp.de-Mitglied

Dabei seit: 23.03.2018
Beiträge: 40


CrocodileDundee ist offline

Lebensdauer von Objekten; Werden Subklassen nicht mit zerstört?

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

Hallo zusammen,
habe eine Klasse, in der ich wiederum eine Klasse instanziere:

C#-Code:
public class Class1
{
    public Subclass SubKlasse = new Subclass();
    ....
}

In meiner Main-Routine instanziere ich dann Class1:

C#-Code:
Klasse1 = new Class1();

so daß ich dann auch auf die SubKlasse zugreifen kann.

C#-Code:
Klasse1.SubKlasse.Prop = 0;

Soweit alles gut.

Wenn ich nun aber die Klasse1 zerstöre und später wieder
instanziere

C#-Code:
Klasse1 = null;
...
Klasse1 = new Class1();

bekomme ich eine Exception, weil anscheinend die Instanz der Subklasse noch immer im Speicher ist.
Kann das sein? Wird die Subklasse nicht mit zerstört?

Vielen Dank!
06.08.2019 11:36 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.324
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

Auf den ersten Blick kann es nicht sein, dass die SubClass Instanz noch im Speicher hängt.
Wenn dein Objekt auf Null gesetzt wird, geht die alte Instanz samt Daten verloren.
Von deinem Code her, wäre deine SubClass mit einem neuen Objekt auch direkt wieder instanziert.

Du solltest auch mit Properties arbeiten.
Direkte Zugriffe auf die Felder einer Klasse verstoßen gegen die Kapselung der Daten in der OOP!
Bitte mal die Exception posten, diese kann hier nicht korrekt sein oder dein Code passt nicht/ist nicht korrekt!

T-Virus
06.08.2019 11:44 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
unconnected unconnected ist männlich
myCSharp.de-Mitglied

avatar-3200.jpg


Dabei seit: 13.08.2006
Beiträge: 849
Entwicklungsumgebung: VS2017 Enterprise,VS Code
Herkunft: Oerlinghausen/NRW


unconnected ist offline

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

Hi,

kommt immer darauf an was Du in deine Class1 oder Subclass so treibst. Wenn das wirklich wie dargestellt nur simple POCOS sind, sollte das tatsächlich so funktionieren.

Die erste Instanz würde aber trotzdem noch eine weile im Speicher verbleiben, bis der Garbage Collector sich bemüht das Ding mal endgültig aus dem Speicher zu werfen.

Hast Du nun irgendwelche Resourcen gebunden, die nicht vernünftig abgeräumt wurden, kann es durchaus zu Exceptions kommen.

Ausserdem kann man noch sehr böse Sachen in Konstruktor oder Property Machen die solche Sachen hervorrufen. Aber wie T-Virus schon schreibt ohne Exception oder Code kann man hier nur raten.
06.08.2019 14:18 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
CrocodileDundee
myCSharp.de-Mitglied

Dabei seit: 23.03.2018
Beiträge: 40

Themenstarter Thema begonnen von CrocodileDundee

CrocodileDundee ist offline

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

OK, ich denke ich hab das Problem anscheinend nicht ausführlich genug geschildert.

Im Grund genommen geht es darum, daß ich eine private Property ändern möchte, die nur über den Konstruktor erreichbar ist.
Konkret geht es darum, daß ich ein Objekt ("Klasse1") instanziere, wobei ich den Namen einer COM-Schnittstelle im Konstruktor angeben muss.

C#-Code:
Class1 Klasse1 = new Class1(COM1);

War es die falsche Schnittstelle (d.h. keine Kommunikation), war der Plan, das Objekt auf "null" zu setzen, und mit dem Namen einer anderen Schnittstelle neu zu instanzieren.

C#-Code:
Klasse1 = null;
Klasse1 = new Class1(COM2);

Beim neuen Instanzieren von Class1 tritt nun die Exception auf.
Der Fehler tritt da auf, wo der Konstruktor der Subklasse durchlaufen wird.

C#-Code:
public class Class1(string COMPortName)
{
    public Subclass SubKlasse = new Subclass();
    ...
}


public class Subclass
{
    DataTable dt = new DataTable();

    public Subclass()
    }
        dt.Columns.Add("Sp1");      // Hier wird die Exception geworfen
        dt.Columns.Add("Sp2");
        dt.Columns.Add("Sp3");
    }
}

Der Compiler meldet zur Laufzeit:
"Additional information: Eine Spalte names 'Sp1' gehört bereits zu dieser DataTable."

Ich kann mir das nur so erklären, daß das Objekt noch im Speicher hängt und noch nicht vom Garbage Collector bereinigt wurde.
Einen "GC-Collect()" hab ich auch schon eingefügt, bringt aber auch nix.

Danke!
06.08.2019 14:41 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Taipi88 Taipi88 ist männlich
myCSharp.de-Mitglied

avatar-3220.jpg


Dabei seit: 02.02.2010
Beiträge: 972
Entwicklungsumgebung: VS 2010
Herkunft: Mainz


Taipi88 ist offline

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

Hi,

du hast Recht und auch wieder nicht.

Du arbeitest beim zweiten Aufruf offenkundig mit der selben Instanz der Datentabelle - das ist ganz offensichtlich aber kein GarbageCollection-Fehler - sondern ein Fehler auf deiner Seite.

Dein Code hier könnte nicht kompilieren, ich habe ihn somit folgendermaßen gestaltet:

C#-Code:
using System.Data;

namespace ConsoleApp8
{
    class Program
    {
        public static void Main(string[] args)
        {
            var Klasse1 = new Class1("COM2");
            Klasse1 = null;
            Klasse1 = new Class1("COM1");
        }
    }

    public class Class1
    {
        public Subclass SubKlasse = new Subclass();

        public Class1(string COMPortName)
        {

        }
    }

    public class Subclass
    {
        DataTable dt = new DataTable();

        public Subclass()
        {
            dt.Columns.Add("Sp1");      // Hier wird die Exception geworfen
            dt.Columns.Add("Sp2");
            dt.Columns.Add("Sp3");
        }
    }
}

Führt man das aus - funktioniert es problemlos. Um dir allerdings einen Hinweis zu geben:
Deklariert man nun z.B. die DataTable als static, also:

C#-Code:
static DataTable dt = new DataTable();

Dann wird einem exakt die von dir genannte Exception um die Ohren gehauen. Mein Tipp: Mach dich auf die Suche wo du etwas ähnliches machst - der Code der dem Forum zur Verfügung steht ist jedenfalls nicht zu dieser Exception in der Lage.

LG
06.08.2019 14:58 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Th69
myCSharp.de-Poweruser/ Experte

avatar-2578.jpg


Dabei seit: 01.04.2008
Beiträge: 3.365
Entwicklungsumgebung: Visual Studio 2015/17


Th69 ist offline

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

Das "auf null setzen" ist überflüssig, wenn direkt darauf wieder ein neues Objekt erzeugt wird (nicht, daß du dir das als Pattern aneignest ;-)
06.08.2019 19:31 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
CrocodileDundee
myCSharp.de-Mitglied

Dabei seit: 23.03.2018
Beiträge: 40

Themenstarter Thema begonnen von CrocodileDundee

CrocodileDundee ist offline

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

Zitat von Taipi88:
Hi,
Deklariert man nun z.B. die DataTable als static, also:

C#-Code:
static DataTable dt = new DataTable();

Dann wird einem exakt die von dir genannte Exception um die Ohren gehauen.
LG

Du hattest Recht, die DataTable war als static deklariert.

Also sind dann anscheinend statische Properties einer Klasse auch dann noch im Speicher,
selbst wenn kein Objekt der Klasse mehr existiert.

Kann es ein, daß diese Properties dann über die gesamte Lebensdauer des Programms im Speicher gehalten werden?
08.08.2019 08:51 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Taipi88 Taipi88 ist männlich
myCSharp.de-Mitglied

avatar-3220.jpg


Dabei seit: 02.02.2010
Beiträge: 972
Entwicklungsumgebung: VS 2010
Herkunft: Mainz


Taipi88 ist offline

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

Hi,

siehe auch:  https://docs.microsoft.com/de-de/dotnet/...keywords/static

Solche statischen Objekte sind per AppDomain (also i.d.R. je Programm) einmalig vorhanden - und unter normalen Umständen vermeidet man die Verwendung dieses Modifikators. (Gibt einige Ausnahmen - eine DataTable ist aber definitiv und unter keinen Umständen ein Kandidat für eine solche Ausnahme)

--> Solange du die MSDN dazu nicht gelesen und verstanden hast solltest du static dementsprechend überhaupt nicht verwenden.

LG
08.08.2019 09:07 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Th69
myCSharp.de-Poweruser/ Experte

avatar-2578.jpg


Dabei seit: 01.04.2008
Beiträge: 3.365
Entwicklungsumgebung: Visual Studio 2015/17


Th69 ist offline

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

Ja, das ist der Sinn von statischen Objekten (es gibt ja auch statische Klassen, von denen keine Instanzen erzeugt werden können - und dann würden deren statischen Member sonst niemals erzeugt werden).
Die statischen Objekte existieren also komplett unabhängig von der Existenz anderer Objekte, sie werden sogar bei direkter Zuweisung schon vor allen anderen Objekten bei Programmstart erzeugt.

Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Th69 am 08.08.2019 09:11.

08.08.2019 09:11 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.324
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

Im Regelfall solltest du solche static Objekte auch vermeiden.
Nur wenn es eine Notwendigkeit sollte man static Objekte verwenden.
Das Problem dabei ist, dass diese Objekte ohne zutun die gesamte Laufzeit lang den benötigten Speicherplatz verbrauchen.
Und je nach Menge/Größe der Objekte kann dies mit der Zeit einiges an RAM sein.
Zusätzlich haben solche Objekte, wie in deinem Fall, dann Seiteneffekte die man ohne genaue Prüfung dann erst einmal nachverfolgen und lösen muss.

T-Virus
08.08.2019 12:57 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Baumstruktur | Brettstruktur       | Top 
myCSharp.de | Forum Der Startbeitrag ist älter als 2 Monate.
Der letzte Beitrag ist älter als 2 Monate.
Antwort erstellen


© Copyright 2003-2019 myCSharp.de-Team | Impressum | Datenschutz | Alle Rechte vorbehalten. | Dieses Portal verwendet zum korrekten Betrieb Cookies. 17.10.2019 07:06