Entwickler-Ecke

Basistechnologien - OOP: Wie arbeite ich mit noch unbekannten Objekten?


Neither - Di 11.11.08 17:27
Titel: OOP: Wie arbeite ich mit noch unbekannten Objekten?
Hallo und einen schönen Abend wünsche ich!

Ich hoffe meine Frage ist noch nicht in dieser Form gestellt worden, zumindest habe ich mit der Suche nichts entsprechendes finden können.

Ich bin relativ neu bei C# und in der OOP, vielleicht mutet meine Frage deshalb etwas seltsam an (oder ist seltsam...)

Ich habe normalerweise und in den Beispielen in vielen Büchern eine Klasse und lege dann ein, oder mehrere Objekte an und arbeite dann im folgenden damit:

MeineKlasse IschbindatOjekt = new MeineKlasse();

So weit so gut - zumindest wenn ich nur ein oder zwei Objekte habe.

Jetzt habe ich aber einen Ordner mit vielen hunderten XML-Dateien (oder sonstwas), die ich bearbeiten will.
Wie gehe ich jetzt vor? Ich will jede Datei als ein Objekt ansteuern und dann auf dessen Methoden und Attribute zugreifen.

Ich kann ja nicht 2000 Deklarationen machen, vor allem wenn sich die Dateien täglich ändern können in ihren Namen und auch in der tatsächlichen Anzahl variieren?!

Oder lege ich tatsächlich nur _ein_ Objekt an, mache ich eine Schleife und weise dem Objekt dann den Inhalt einer Datei zu, bearbeite es als dieses Objekt und nach der Bearbeitung in nächsten Schleifendurchlauf bekommt das Objekt die nächste Datei als Attribut zugewiesen??? Das kann es doch eigentlich nicht sein, oder doch ?


Hier stehe ich wirklich auf dem Schlauch, da alle Beispiele immer nur ein oder zwei Objekte haben. Hilfe!

Danke im Voraus!
Stephan


JüTho - Di 11.11.08 18:41

Hallo und :welcome:

Hunderte von xml-Dateien... Eine allgemeingültige Antwort kann man nicht geben; das hängt von der konkreten Anforderung ab. Wenn sie nacheinander bearbeitet werden, dann ist es sinnvoll, das Objekt innerhalb einer Schleife zu instanziieren und zu bearbeiten; am Ende der Schleife ist es weg:

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
foreach(string[] files in Directory.GetFiles(...))
{
   XmlDocument doc = new XmlDocument();
   doc.Load( XmlReader.Create(filename));
   //  jetzt doc verarbeiten
}
//  jetzt ist die Variable doc weg

Wenn die Daten insgesamt verarbeitet werden sollen, dann kommen List<EineKlasse> und EineKlasse-Array in Frage. Bitte beachte: Ein Array ist (fast immer) statisch und kann in der Größe kaum verändert werden; die List<T> ist sehr flexibel. Beispiel:

C#-Quelltext
1:
2:
3:
DirectoryInfo di = new DirectoryInfo(@"c:\MyDir");
//  zwischenspeichern im Array
FileInfo[] fi = di.GetFiles("*.exe");

Jetzt können alle Elemente der Variablen fi verarbeitet werden. Diese Variable ist bis zum Ende des aktuellen Blocks gültig.

Es gibt noch andere Situationen und Wege; aber ich hoffe, ich habe es etwas verdeutlichen können. Jürgen


Ralf Jansen - Di 11.11.08 23:12

Wenn es XML Dateien sind, ist deren Struktur eindeutig? Oder anders gefragt gibt es zu den XML-Dateien ein XSD Schema?


Neither - Mi 12.11.08 15:32

user profile iconJüTho hat folgendes geschrieben Zum zitierten Posting springen:
... Wenn sie nacheinander bearbeitet werden, dann ist es sinnvoll, das Objekt innerhalb einer Schleife zu instanziieren und zu bearbeiten; am Ende der Schleife ist es weg:

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
foreach(string[] files in Directory.GetFiles(...))
{
   XmlDocument doc = new XmlDocument();
   doc.Load( XmlReader.Create(filename));
   //  jetzt doc verarbeiten
}
//  jetzt ist die Variable doc weg

...
Es gibt noch andere Situationen und Wege; aber ich hoffe, ich habe es etwas verdeutlichen können. Jürgen


Oh, ja sehr sogar! :D
Und auch noch vielen Dank für die schnelle Antwort! :D

Die Dateien werden in diesem Fall tatsächlich nacheinander abgearbeitet, deshalb erscheint mir die erste Lösung als die passendste.
Die zweite werde ich im Hinterkopf behalten und mir einmal genauer ansehen wenn ich etwas Ruhe habe.

Zur Sicherheit noch eine Nachfrage: Ist die Lebensdauer des erzeugten Objekts durch die Schleife begrenzt (also "stirbt" das Objekt am Ende seines natürlichen Lebensraumes, der Schleife bei jedem Schleifendurchlauf) oder "stirbt" das Objekt durch das neue Erzeugen am Schleifenanfang.
Ich hoffe der erste Fall trifft zu, dann hätte ich wenigstens das richtig verstanden ;-)

Viele Grüße und vielen Dank
Stephan :-)


Neither - Mi 12.11.08 16:11

user profile iconRalf Jansen hat folgendes geschrieben Zum zitierten Posting springen:
Wenn es XML Dateien sind, ist deren Struktur eindeutig? Oder anders gefragt gibt es zu den XML-Dateien ein XSD Schema?


Die XML-Dateien sind eindeutig.
Entscheidend ist aber in diesem Falle gar nicht so sehr, dass es sich um XML-Dateien handelt.
Diese werden zwar nach bestimmten Merkmalen aus dem eigenen Inhalt hin bearbeitet, im Kern geht es aber um eine Verteilung mit einer Entscheidung Kopieren oder Verschieben in verschiedene Zielordner.

Bisher arbeitet ein VB.Net Programm ganz klassisch und arbeitet für jedes Kriterium den Ordner erneut und vollständig mit allen XML-Dateien komplett durch. Da die Dateien auf mehr als ein dutzend Kriterien/ Regeln untersucht werden, ist das recht aufwändig. Aktuell wird der Ordner so 15 mal mit allen (jeweils noch vorhandenen) XML-Dateien durchlaufen!

Das C#-Programm soll im Gegensatz dazu sich nacheinander alle Dateien einmalig (!) und einzeln nehmen und jede Datei als Objekt mit entsprechenden Methoden nach den Regeln abarbeiten.
Das könnte man natürlich auch mit einem VB.Net Programm machen können, aber um sich von klassischen, erlernten "Rollen" und Lösungswegen zu trennen, ist es manchmal doch hilfreich einen ganz neuen Weg einzuschlagen ;-)


UGrohne - Mi 12.11.08 16:13

user profile iconNeither hat folgendes geschrieben Zum zitierten Posting springen:
Die Dateien werden in diesem Fall tatsächlich nacheinander abgearbeitet, deshalb erscheint mir die erste Lösung als die passendste.
Die zweite werde ich im Hinterkopf behalten und mir einmal genauer ansehen wenn ich etwas Ruhe habe.

Eine weitere Alternative wäre die Verwendung von Serialisierung. Du baust Dir also ein Objekt, das die Struktur der XML-Datei nachbildet und per Serialization kannst Du dieses Objekt automatisch mit Daten befüllen. Zu den Basics dazu hab ich in der Library ein Tutorial geschrieben, mit Attributen kannst Du das Verhalten des Serializers anpassen. Ist aber vielleicht ein wenig Overkill, und wenn die XMl-Dateien nicht dieselbe Struktur haben (bereits gegebenes Stichwort Schema) nicht praktikabel.

user profile iconNeither hat folgendes geschrieben Zum zitierten Posting springen:
Zur Sicherheit noch eine Nachfrage: Ist die Lebensdauer des erzeugten Objekts durch die Schleife begrenzt (also "stirbt" das Objekt am Ende seines natürlichen Lebensraumes, der Schleife bei jedem Schleifendurchlauf) oder "stirbt" das Objekt durch das neue Erzeugen am Schleifenanfang.
Ich hoffe der erste Fall trifft zu, dann hätte ich wenigstens das richtig verstanden ;-)

Jein. Du hast beim nächsten Schleifendurchgang keine Möglichkeit mehr, auf die Instanz zuzugreifen, aber im Hintergrund existiert es noch. Das ist eine andere Verhaltensweise in .NET, darin werden die Instanzen vom Garbage Collector erst nach einiger Zeit aufgeräumt, aber im Endeffekt trifft Deine erste Aussage zu.


JüTho - Mi 12.11.08 16:23

user profile iconNeither hat folgendes geschrieben Zum zitierten Posting springen:
Zur Sicherheit noch eine Nachfrage: Ist die Lebensdauer des erzeugten Objekts durch die Schleife begrenzt (also "stirbt" das Objekt am Ende seines natürlichen Lebensraumes, der Schleife bei jedem Schleifendurchlauf) oder "stirbt" das Objekt durch das neue Erzeugen am Schleifenanfang.
Ich hoffe der erste Fall trifft zu, dann hätte ich wenigstens das richtig verstanden ;-)

UGrohnes "Jein" gefällt mir als Antwort. Ich würde trotzdem eher die zweite Variante als zutreffend ansehen: Durch das Erzeugen der neuen Instanz wird die vorherige als "ungültig" deklariert und dem GC (Garbage Collector) überlassen; damit steht sie schließlich nicht mehr zur Verfügung.

Eine Diskussion darüber hatte ich unter Variablentypdeklaration in oder außerhalb von Schleifen? [http://www.mycsharp.de/wbb2/thread.php?threadid=50458] gelesen.

Jürgen


UGrohne - Mi 12.11.08 16:31

user profile iconJüTho hat folgendes geschrieben Zum zitierten Posting springen:

UGrohnes "Jein" gefällt mir als Antwort. Ich würde trotzdem eher die zweite Variante als zutreffend ansehen: Durch das Erzeugen der neuen Instanz wird die vorherige als "ungültig" deklariert und dem GC (Garbage Collector) überlassen; damit steht sie schließlich nicht mehr zur Verfügung.

Also ich würde sagen, dass dieses "ungültig" deklarieren bereits beim Verlassen des ersten Schleifendurchlaufs geschieht, denn das ist der Zeitpunkt, an dem ich nicht mehr darauf zugreifen kann, denn sonst würde sowas wie das Folgende ja nicht schon vom Compiler angemeckert werden:

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
            for (int i=0; i < 10; i++)
            {
                Console.WriteLine(i2.ToString());
                int i2 = 0;
                i2++;
                Console.WriteLine(i2.ToString());
            }


Kha - Mi 12.11.08 19:46

user profile iconUGrohne hat folgendes geschrieben Zum zitierten Posting springen:
Also ich würde sagen, dass dieses "ungültig" deklarieren bereits beim Verlassen des ersten Schleifendurchlaufs geschieht, denn das ist der Zeitpunkt, an dem ich nicht mehr darauf zugreifen kann, denn sonst würde sowas wie das Folgende ja nicht schon vom Compiler angemeckert werden:

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
            for (int i=0; i < 10; i++)
            {
                Console.WriteLine(i2.ToString());
                int i2 = 0;
                i2++;
                Console.WriteLine(i2.ToString());
            }
In der Theorie (und die zählt) dürftest du Recht haben. Der Scope der Variablen endet am Blockende, damit existiert ab dort keine Referenz mehr auf die Instanz und sie kann vom GC erfasst werden.
In der Praxis werden die Variablen in der Schleife alle in derselben CIL-Variablen gespeichert sein, womit die Referenz wahrscheinlich (=keine Ahnung) erst beim
user profile iconJüTho hat folgendes geschrieben Zum zitierten Posting springen:
Erzeugen Zuweisen der neuen Instanz
verloren ginge. Das sind aber ebenso wie der Zeitpunkt, an dem der GC aktiv wird, Implementierungsdetails und dürfte sich im Mikrosekundenbereich abspielen. Also würde ich Uwes Antwort als Musterantwort ansehen.


UGrohne - Mi 12.11.08 19:53

user profile iconKha hat folgendes geschrieben Zum zitierten Posting springen:
... Also würde ich Uwes Antwort als Musterantwort ansehen.

:dance: