Entwickler-Ecke

IO, XML und Registry - Serialization


Maddin_404 - Mo 12.11.18 18:14
Titel: Serialization
Hallo und zwar habe ich mich gestern mit Serialization in c# beschäftigt, da ich mir gerade einen Liquid.Rechner (Für E-Zigaretten/Dampfer :D) programmiere.
da ich erst seit einer Woche mich mit programmieren beschäftige bin ich noch sehr unerfahren und Google viel aber irgendwie finde ich nichts dazu;
Und zwar mein Problem ist wie ich mehrere Sachen in einer Datei speichern kann. bzw das diese nicht überschrieben wird sondern was dazu geschrieben wird??
Bisher habe ich nur unzählige Tutorials gefunden wo halt nur einmal was gespeichert wird und das dann wieder abgerufen werden kann soweit habe ich das auch hin bekommen.

Und wenn ich denn z.B in meinem Fall für den Liquid.Rechner mir meine errechneten Ergebnisse speicher klappt das auch aber ich wenn ich den nächsten wert speicher ist das alte wieder weg.
Ich habe schon was gelesen von; txt. Datei laden und löschen und neue erstellen aus alter und neuer aber ich hab absolut keine Idee wie das gehen soll ;/

So sieht mein code momentan aus;


C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
 [Serializable]
    public class Rezepte
    {
        public string Name { get; set; }
        public string Angaben { get; set; }
        public string Arom { get; set; }
        public string Bas { get; set; }

        public void Save(string path)
        {
            System.IO.FileStream FS = new System.IO.FileStream(path, System.IO.FileMode.Create);
            BinaryFormatter BF = new BinaryFormatter();

            BF.Serialize(FS, this);
            FS.Dispose();
        }

        public Rezepte Load (string path)
        {
            Rezepte US = new Rezepte();

            System.IO.FileStream FS = new System.IO.FileStream(path, System.IO.FileMode.Open);
            BinaryFormatter BF = new BinaryFormatter();

            US = (Rezepte)BF.Deserialize(FS);

            return US;

        }


Th69 - Mo 12.11.18 18:52

Hallo und :welcome:

kennst du schon Array [https://docs.microsoft.com/de-de/dotnet/api/system.array?view=netframework-4.7.2]s oder List<T> [https://docs.microsoft.com/de-de/dotnet/api/system.collections.generic.list-1?view=netframework-4.7.2]?
Mit diesen kannst du dann beliebige viele Objekte speichern und auch serialisieren, z.B.

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
using System.Collection.Generics;
using System.IO;

public void Save(string path, List<Rezept> recipes)
{
    using (FileStream fileStream = new FileStream(path, FileMode.Create))
    {
        BinaryFormatter binaryFormatter = new BinaryFormatter();

        binaryFormatter.Serialize(fileStream, recipes);
    }
}

Am besten du erzeugst dir eine eigene Klasse für diese Methode und läßt die Klasse Rezept (in Einzahl, da es ja nur genau 1 Rezept repräsentiert) so wie sie jetzt ist. Analog dann die Load-Methode implementieren.

Ich habe im Code oben auch gleich die using-Anweisung benutzt, damit man auf das (manuelle) Dispose() verzichten kann (weiterer Vorteil ist, daß auch im Falle einer Exception diese Methode aufgerufen wird).


Ralf Jansen - Mo 12.11.18 18:52

Rezepte als Klassenname als Plural impliziert das das mehrere wären es ist aber im Moment nur ein Rezept.

Was du machen könntest.

1.) Erstelle eine weitere Klasse Rezept
2.) Verschiebe die 4 Properties in deiner Rezepte Klasse nach Rezept
3.) Leite Rezepte von List<Rezept> ab
4.) mache Load static


Maddin_404 - Mo 12.11.18 20:19

Hey danke erstmal :D pkt 1 und 2 habe ich; wo genau muss ich jetzt die Ableitung machen? :oops:

bin am probieren , aber mehr wie Fehler Meldungen habe ich noch nicht geschafft :/

Moderiert von user profile iconTh69: Vollzitat entfernt.


Ralf Jansen - Mo 12.11.18 21:08

Bisher hattest du diese Klasse

C#-Quelltext
1:
2:
3:
4:
public class Rezepte
{
...
}

Die solltest du in

C#-Quelltext
1:
2:
3:
4:
public class Rezepte : List<Rezept>
{
...
}

ändern.

Du solltest natürlich auch versuchen zu verstehen was eine List<T> ist und was es mit Vererbung (Ableitung) auf sich hat. Sonst wirst du Schwierigkeiten haben die nächsten (von mir ungenannten) Schritte zu verstehen. Primär das dann kommende "wie benutze ich das jetzt" ;)


Maddin_404 - Mo 12.11.18 21:22

Ja da ist was dran :oops: , dann werde ich mich wohl doch erstmal weiter mit den Grundlagen beschäftigen :)
Aber schon mal schön ein Forum gefunden zu haben wo man auch doofe fragen stellen darf :D :P

Moderiert von user profile iconTh69: Vollzitat entfernt.


Th69 - Di 13.11.18 10:17

Ableitung halte ich hier nicht für sinnvoll. Besser eine einfache Aggregation/Komposition, d.h. als Membervariable:

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
public class Rezeptverwaltung
{
  public List<Rezept> Rezepte { get; private set; } = new List<Rezept>(); // alternativ Initialisierung im Konstruktor (falls ältere C#-Version)

  public void Load()
  {
    // ...
  }

  public void Save()
  {
    // ...
  }
}


PS: Bitte keine Vollzitate!


Maddin_404 - Di 13.11.18 21:11


C#-Quelltext
1:
public List<Rezept> Rezepte { get; private set; } = new List<Rezept>();                    


Das muss jetzt in meinem Fall in die Klasse Rezepte oder Rezept?
sorry ich seh das gerade irgendwie echt nicht durch :/ , Ich Habe es jetzt in der Klasse Rezept, da kommt keine Fehlermeldung, aber in der Klasse Rezepte kommt der Fehler das Membernamen dürfen nicht dem einschließenden Typ entsprechen.

aber normal müsste es doch in die Klasse Rezepte? oder hab ich da was falsch verstanden? :oops:


Th69 - Mi 14.11.18 08:48

Ja, in die Klasse, welche die Rezepte verwaltet (da Klassenmember nicht denselben Namen wie die Klasse haben dürfen, habe ich ja extra die Klasse umbenannt - alternativ kannst du der Eigenschaft einen anderen Namen geben, wie RezeptListe o.ä.).