{the magic lies between the brackets}

Monat: April 2013 (Seite 1 von 1)

[C#/.NET] – XML Deserialisierung von Objekten

Bezugnehmend auf die Serialisierung eines Objektes in C#, möchte man das gespeicherte Objekt in Form eines XML-Files sicher wieder laden können.
Auch hier bietet das .NET-Framework eine einfach Möglichkeit.

Der erste Schritt ist natürlich – wie immer – den Namespace einzubinden:

using System.Xml.Serialization;

Nun erstellt man ein Objekt vom Typ XmlSerializer und definieren, von welchem Typ die serialisierten Daten sind (hier: User )

XmlSerializer userDeserializer = new XmlSerializer(typeof(User)); 

Um die Datei nun einzulesen, benötigen wir einen StreamReader, wir erstellen also ein Objekt davon:

StreamReader reader = new StreamReader(@"C://xmlfile.xml"); //Parameter des Konstruktors ist hier der Pfad zur XML-Datei

Zur Erinnerung, die Datei sah so aus:

<?xml version="1.0" ?> 
  <User>
    <name>Fabian</name> 
    <index> 1 </index>
  </User> 

Nun brauchen wir noch ein Objekt vom Typ User, ich nenne das Objekt mal userFabian.

 User userFabian = new User(); 

Nun weisen wir diesem Objekt, die gespeicherten Werte via Deserialisierung des Files zu. Als Parameter des XMLSerializer übergeben wir das StreamReader-Objekt

 userFabian = (User)userDeserializer.Deserialize(reader); 

Ein Cast zum Typ des Objektes (User) ist, trotz der vorigen Angabe unerlässlich.

Anschließend schließen wir den StreamReader und das Objekt wurde erstellt.

reader.Close();

Fertig!

Der Frühling ist da

Was lange währt, wird endlich gut!
Am Wochenende gab es seit langer Zeit endlich wieder Temperaturen jenseits der 20°C.
Die Motorrad-Saison ist offiziell eröffnet!

Was also tun? Am Samstag erstmal mit den Jungs aus dem SVRider-Forum eine Runde zur Löwensteiner Platte und gut 400km später wieder zu Hause.
Sonntag 11:30 Treffen in Wiesensteig, ab geht’s auf die Alb und ab Richtung Lautertal.
Zwischenstation Zwiefalten um 13:45Uhr, erstmal was essen.

Nach der Verpflegung, ab auf das Bike und die Heimreise antreten.
Ankunft kurz vor 17 Uhr.

Ein hammer Wochenende geht zu Ende… auf viele weitere

So nebenbei habe ich die ersten 1000km auf meinem Bike abgespult und die Sturzpads(R&G für SV650S Vollverkleidung) montiert

[C#/.NET] – Unterschied zwischen new virtual und override

Wer mit Vererbung arbeitet, hat sicher schon mit dem Begriff override zu tun gehabt.
Was es aber auch gibt ist das Schlüsselwort new bzw. virtual .
Wo ist der Unterschied?

Erstellen wir ein Beispiel. Wir haben eine Klasse mit der Bezeichnung Engineer:

     class Engineer
    {
        protected string name;
        protected double billingRate;

        public Engineer(string name, double billingRate)
        {
            this.name = name;
            this.billingRate = billingRate;
        }

        public virtual double calcMoney(double hours) //virtual ermöglicht das überschreiben der Methode in abgeleiteten Klassen
        {
            return billingRate * hours * 2.0d; //Standardfunktion, falls nicht überschrieben
        }

    }  

Hier haben wir die virtuelle* Methode calcMoney.

virtual: Mit dem virtual-Schlüsselwort kann eine Methode, eine Eigenschaft, ein Indexer oder eine Ereignisdeklaration geändert und in einer abgeleiteten Klasse überschrieben werden.

(Quelle: MSDN)

Nun erstellen wir eine Klasse CivilEngineer (Bauingenieur) und leiten von Engineer-Klasse ab:

     class CivilEngineer : Engineer
    {
        public CivilEngineer(string name, double billingRate)
            : base(name, billingRate)
        {
            this.name = name;
            this.billingRate = billingRate;
        }

        public override double calcMoney(double hours) //Hier wird die Funktion aus der Klasse Engineer
        { //überschrieben, d.h. hier wird jetzt diese Funktion verwendet, anstatt der Basisfunktion
            return billingRate * hours * 1.5d; //Faktor auf 1.5d geändert
        }
    } 

Der Konstruktor ruft hier zuerst den Konstruktor der Basisklasse (Engineer) auf base(name, billingRate) und übergibt die Parameter der CivilEngineer-Klasse.

Nun überschreiben wir die Methode der Basisklasse und ersetzen Sie durch calcMoney der CivilEngineer Klasse.

Jetzt erstellen wir ein Objekt des Engineers und ein Objekt des CivilEngineers.

             CivilEngineer c1 = new CivilEngineer("John",15d);
            Engineer e1 = new Engineer("Keith", 10d); 

Nun erstellen wir eine Liste von Engineers (List<Engineer>) und fügen beide Objekte dieser Liste hinzu:

             List elist = new List();
            elist.Add(c1);
            elist.Add(e1); 

Nun rufen wir bei beiden Objekten die Funktion calcMoney() auf.

             e1.calcMoney(10); //Es wird die Methode Engineer.calcMoney() aufgerufen (Ist ja klar!)
            c1.calcMoney(10); // Es wird die überschriebene Methode CivilEngineer.calcMoney() aufgerufen (Soweit, so gut. Passt alles) 

Jetzt rufen wir die calcMoney()-Methode innerhalb einer foreach-Schleife in der Liste auf:

             foreach (Engineer eng in blalist) //Alle Objekte, egal ob abgeleitet oder nicht, sind vom Typ Engineer
            {
                eng.calcMoney(10);
            } 

Beim ersten Durchlauf wird jetzt die Funktion des Objektes c1 aufgerufen, da dieses zuerst zur Liste hinzugefügt wurde.
Es wird, wie erwartet die überschriebene Methode der abgeleiteten Klasse (CivilEngineer) aufgerufen (also CivilEngineer.calcMoney()), da wir diese in der Klasse Engineer überschrieben (override) haben.

Im darauffolgenden Durchlauf wird jetzt die Funktion des Objektes e1 aufgerufen:
Es wird die Methode der Klasse Engineer aufgerufen, da das Objekt vom Typ Engineer ist – also Engineer.calcMoney(10).

Dies war jetzt mit den Schlüsselwörtern virtual und override.


Jetzt kommen wir zu new:

Fügen wir eine Klasse TankEngineer hinzu, welche die Methode calcMoney() hat, aber hier mit dem new Schlüsselwort deklariert:

    class TankEngineer : Engineer
    {
        public TankEngineer(string name, double billingRate) //Konstruktor der abgeleiteten Klasse
            : base(name, billingRate) //Ruft den Konstruktor der Basisklasse auf, da es von dieser ableitet (benötigt zur Existenz)
        //gleiche Parameter!
        {
            this.name = name; //Zuweisung der Eigenschaften (vererbt)
            this.billingRate = billingRate;
        }

        public new double calcMoney(double hours) //Hier wird die Funktion aus der Klasse Engineer
        { //verdeckt (!) und NICHT überschrieben
            return billingRate * hours * 3.0d; //Faktor auf 3.0d geändert
        }
    }

Nun erstellen ein Objekt vom Typ TankEngineer und fügen es der vorigen Liste mit den zwei anderen Objekten hinzu:

 TankEngineer t1 = new TankEngineer("Robert", 20d); 
 elist.Add(t1); // Füge den TankEngineer hinzu 

Rufen wir nun die Methode calcMoney direkt über das Objekt auf,

  t1.calcMoney(10); // Ruft TankEngineer.calcMoney auf, da vom Typ TankEngineer und Basismethode verdeckt 

Wird die Methode TankEngineer.calcMoney aufgerufen, da diese in der Klasse TankEngineer existiert.

Gehen wir aber nun per foreach wieder durch die Liste (elist):

             foreach (Engineer eng in elist)
            {
                eng.calcMoney(10);
                // 3. Durchgang (t1), ruft die Engineer.calcMoney-Methode auf, da diese existent ist und durch 
                // das new-Schlüsselwort nur verdeckt wurde. 
            } 

so wird hier jetzt die Methode der Basisklasse aufgerufen, da die Liste nur Objekte vom Typ Engineer hält und die Methode nicht überschrieben, sondern nur verdeckt wurde.
D.h. es waren zur Laufzeit beide Methoden des gleichen Namens in beiden Klassen verfügbar.

Zur Veranschaulichung habe ich euch ein kleines Projekt gebastelt, in welchem ihr durch Debugging selbst sehen könnt, wie override bzw. new arbeiten: DOWNLOAD

[C#/.NET] – XML Serialisierung von Objekten

Viele Daten möchte man schnell und unkompliziert abspeichern und wieder in das Programm laden.
Das .NET Framework bietet hierfür unter anderem die Klasse XmlSerializer im Namespace System.Xml.Serialization an.

Der erste Schritt ist natürlich – wie immer – den Namespace einzubinden:

  using System.Xml.Serialization; 

Danach erstellen wir eine Klasse d.h. Bauplan für die zu serialisierenden Objekte:
In meinem Beispiel habe ich jetzt eine Klasse, welche zwei Attribut (Properties) hält.
Mit dem ersten Konstruktor kann ich die Werte direkt zuweisen.
Der zweite Konstruktor wird für die XMLSerialisierung benötigt. Dieser wird vom XMLSerializer aufgerufen.

   
public class User   {    
   
     public string name { get; set; }        
     public int index { get; set; }      

     public User(string name, int index) {          
         this.name = name;      
         this.index = index; 
     }

     public User() { 
 
     }   
} 

Des „schwerste Schritt ist jetzt eigentlich schon geschafft.

Jetzt erstellen wir ein Objekt der Klasse User und füllen die Properties.

 User currentuser = new User("Fabian",1); 

Eine Liste von Objekten (List<User>) zu serialisieren ist natürlich auch möglich und vom Prinzip her identisch.

Nun erstellen zum eigentlichen Thema, der Serialisierung:
Wir erstellen nun ein Objekt der Klasse XmlSerializer:

  XmlSerializer xmlserializer = new XmlSerializer(typeof(User)); 

Hier übergeben wir dem XML-Serialisierer um welche Art von Objekt (typeof()) es sich handelt.
Hier füllen wir in unserem Beispiel typeof(User) ein, bei einer Liste von unserem Objekt typeof(List<User>).

Nun benötigen wir zum Speichern von Dateien auf der Festplatte einen FileStream:

 FileStream str = new FileStream(@"C:\User\xyz\myXMl.xml", FileMode.Create); 

Als Parameter übergeben wir den Speicherpfad und die Option, die dem FileStream sagt, dass er eine Datei erstellen (Create) soll.

Anschließend führen wir die Serialisierung durch:

  xmlserializer.Serialize(str,currentuser); 

Wir übergeben dem XMLSerializier-Objekt hier den den FileStream und unser User-Objekt (currentuser).
Der Serialisierer kümmert sich um den Rest, also Serialisierung und Abspeichern etc.

Zum Schluss einfach den FileStream schließen:

 str.Close(); 

Voilà wir haben unser serialisiertes Objekt auf der Fesplatte. Die Datei sollte in etwa so aussehen:

 <?xml version="1.0" ?> 
- <User>
    <name>Fabian</name> 
    <index> 1 </index>
  </User> 

iGO8 – Google Maps Routen importieren

Ich besitze ein Motorradnavi, welches Nav N Go iGO8 als Software verwendet.
Nun wurde im Forum eine Route per Google Maps erarbeitet und verteilt, mein Problem war nun das Importieren der Route in mein Navigationssystem.
Letztendlich habe ich es geschafft und beschriebe nun hier den Weg:

1. Man öffne die benötigte Route im Browser.

2. Nun benötigt man ein externes Plugin(http://www.elsewhere.org/journal/gmaptogpx).
Dieses wird über einen Link bereitgestellt, welchen man als Bookmark speichern muss und nachdem die Route in GMaps aufgerufen wurde, per Klick darauf ausführt.

3. Dieses Plugin generiert danach eine Textbox mit dem Inhalt der GPX-Datei, den Inhalt kopiert man und fügt ihn per Texteditor in eine Datei mit der Endung *.gpx

4. Nachdem man die GPX-Datei mit Inhalt erstellt hat, öffnet man den Motoplaner(http://www.motoplaner.de/)

5. Auf dieser Seite kann man die GPX-Datei über den Button GPS-Import importieren und anzeigen lassen.

6. Sollte die Route erfolgreich importiert worden sein, so könnt ihr nun die Route exportieren. Wählt dazu das erforderlich Format (in meinem Fall KML4.2) und als Typ Route&Track. Danach könnt ihr noch automatisch weitere Wegpunkte hinzufügen lassen, damit euer Navi keinen anderen Weg einschlägt.

7. Nun speichert ihr die Datei und kopiert sie auf euer Navigationsgerät in den Ordner  ../igo8/content/userdata/route
Sollte der Ordner nicht existieren, so legt ihn an.

8. Nun könnt ihr euer Navi abstecken(sicher entfernen nicht vergessen ;) ) und starten. Um die Route zu laden, wechselt ihr über die Einstellungen in den Expertenmodus. Im Hauptmenü wählt ihr dann den Punkt „Route“. In diesem Untermenü die Route laden und voilà, nun könnt ihr die Route nachfahren