C#.NET * C++ * JAVASCRIPT * PYTHON * DIVERSES
XML * XML-SCHEMA * XPATH * XSL * XSL-FO * SVG * XQUERY * XPROC * ANT



C#.NET / Objekt-Orientierte Programmierung mit C#.NET / C#.NET Interfaces im Einsatz

C#.NET Interfaces im Einsatz

C#.NET Interfaces im Einsatz

➪ In größeren Projekten geht man gern so vor: zuerst wird der gesamte Entwurf in einigen Interfaces deklariert; anschließend machen sich die Developer an die Detail-Implementierung.

Zuerst die Interfaces:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace cs_schulung
{
  public interface IOrt
  {
    int ID { get; set; }
    string Name { get; set; }
    void Add(IEinwohner x);
    List<IEinwohner> Einwohnerliste { get; }
  }
  public interface IEinwohner
  {
    int ID { get; set; }
    string Nachname { get; set; }
    string Vorname { get; set; }
    double Gehalt { get; set; }
    void Add(IKauf x);
    List<IKauf> Kaufliste { get; }
    IOrt Stadt { get; set; }
  }
  public interface IKauf
  {
    int ID { get; set; }
    int IDEinwohner { get; set; }
    string Artikel { get; set; }
    double Einzelpreis { get; set; }
    int Anzahl { get; set; }
    double Gesamt { get; }
    IEinwohner Kunde { get; set; }
  }
}

Die Klasse Ort implementiert das Interface IOrt. Nach der automatischen Generierung der public-Methoden bzw. Properties bleibt nur noch die Detail-Implementierung.


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace cs_schulung
{
  public class Ort : IOrt
  {
    private int _ID;
    private string _Name;
    private List<IEinwohner> _einwohnerliste = new List<IEinwohner>();
    public Ort(int ID, string Name, List<IEinwohner> einwohnerliste, 
                                                 int iD, string name)
    {
      _ID = ID;
      _Name = Name;
      _einwohnerliste = einwohnerliste;
      this.ID = iD;
      this.Name = name;
    }
    public Ort()
    {
    }
    public int ID { get => this._ID; set => this._ID=value; }
    public string Name { get => this._Name; set => this._Name=value; }
    public List<IEinwohner> Einwohnerliste { get => this._einwohnerliste; }
    public void Add(IEinwohner x)
    {
      x.Stadt = this;
      this._einwohnerliste.Add(x);
    }
    public override string ToString()
    {
      return String.Format("ID: {0}, Name: {1}", ID, Name);
    }
  }
}

Ähnlich verläuft das mit der Klasse Einwohner, die das Interface IEinwohner implementiert. Um spätere Ergebnisse sortieren zu können, benötigen Sie noch die Implementierung über IComparable.


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace cs_schulung
{
  public class Einwohner : IEinwohner, IComparable
  {
    private int _ID;
    private string _Nachname, _Vorname;
    private double _Gehalt;
    private List<IKauf> _kaufliste = new List<IKauf>();
    private IOrt _Stadt;
    public int ID { get => this._ID; set => this._ID=value; }
    public string Nachname { get => this._Nachname; set => this._Nachname=value; }
    public string Vorname { get => this._Vorname; set => this._Vorname=value; }
    public double Gehalt { get => this._Gehalt; set => this._Gehalt=value; }
    public List<IKauf> Kaufliste { get { return this._kaufliste; } }
    public IOrt Stadt { get => this._Stadt; set => this._Stadt=value; }
    public void Add(IKauf x)
    {
      x.Kunde = this;
      this._kaufliste.Add(x);
    }
    public int CompareTo(object obj)
    {
        IEinwohner im = (IEinwohner)obj;           
        return Gehalt.CompareTo(im.Gehalt);
    }
    public override string ToString()
    {
      return String.Format("ID: {0}, Name: {1}, VN: {2}", ID, Nachname, Vorname);
    }
  }
}

Bei der Klasse Kauf läuft es analog:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace cs_schulung
{
  public class Kauf : IKauf
  {
    private int _ID, _IDEinwohner, _Anzahl;
    private string _Artikel;
    private double _einzelpreis;
    private IEinwohner _Kunde;
    public int ID { get => this._ID; set => this._ID=value; }
    public int IDEinwohner 
    { 
        get => this._IDEinwohner; 
        set => this._IDEinwohner=value; 
    }
    public string Artikel 
    { 
        get => this._Artikel; 
        set => this._Artikel=value; 
    }
    public double Einzelpreis 
    { 
        get => this._einzelpreis; 
        set => this._einzelpreis=value; 
    }
    public int Anzahl 
    { 
        get => this._Anzahl; 
        set => this._Anzahl=value; 
    }
    public double Gesamt { get { return (Anzahl*Einzelpreis); } }
    public IEinwohner Kunde 
    { 
        get => this._Kunde; 
        set => this._Kunde = value; 
    }
    public override string ToString()
    {
      return $"ID: {ID}, Artikel: {Artikel}, Gesamt: {Gesamt}");
    }
  }
}

In einem ersten einfachen Test erkennen Sie die Zusammenhänge schnell:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace cs_schulung
{
  class Program
  {
    // liest via System.Xml.XmlDocument() ein XML-Dokument in eine List<IOrt>
    static List<IOrt> ReadXML(string filename)
    {
      List<IOrt> ortliste = new List<IOrt>();
      System.Xml.XmlDocument dom = new System.Xml.XmlDocument();
      dom.Load(filename);
      foreach (System.Xml.XmlElement eo in dom.SelectNodes("//Ort"))
      {
        IOrt o = new Ort();
        o.ID = Int32.Parse(eo.SelectSingleNode("id").InnerText);
        o.Name = eo.SelectSingleNode("name").InnerText;
        ortliste.Add(o);
        foreach (System.Xml.XmlElement em in eo.SelectNodes("Einwohner"))
        {
          IEinwohner m = new Einwohner();
          m.ID = Int32.Parse(em.SelectSingleNode("id").InnerText);
          m.Nachname = em.SelectSingleNode("name").InnerText;
          m.Vorname = em.SelectSingleNode("vorname").InnerText;
          m.Gehalt = Double.Parse(em.SelectSingleNode("Gehalt").InnerText);
          o.Add(m);
          foreach (System.Xml.XmlElement ek in em.SelectNodes("Kauf"))
          {
            IKauf k = new Kauf();
            k.Anzahl = Int32.Parse(ek.SelectSingleNode("anzahl").InnerText);
            k.Artikel = ek.SelectSingleNode("bez").InnerText;
            string einzelpreis = ek.SelectSingleNode("preis").InnerText;
            k.Einzelpreis = Convert.ToDouble(einzelpreis, 
                   System.Globalization.CultureInfo.InvariantCulture);
            m.Add(k);
          }
        }
      }
      return ortliste;
    }
    // Alternative: Auswerten mit LINQ
    // liest ein XML-Dokument via System.Xml.Linq.XDocument in List<IOrt>
    static List<IOrt> ReadXMLByLINQ(string filename)
    {
      List<IOrt> ortliste = new List<IOrt>();
      System.Xml.Linq.XDocument xdoc = System.Xml.Linq.XDocument.Load(filename);
      IEnumerable<System.Xml.Linq.XElement> iOrt = xdoc.Descendants("Ort");
      foreach(System.Xml.Linq.XElement iio in iOrt)
      {
        Ort vort = new Ort();
        vort.Name = iio.Element("name").Value;
        vort.ID = Int32.Parse(iio.Element("id").Value);        
        IEnumerable<System.Xml.Linq.XElement> iEinwohner;
        iEinwohner = iio.Descendants("Einwohner");
        foreach (System.Xml.Linq.XElement iim in iEinwohner)
        {
          Einwohner m = new Einwohner();
          m.Nachname = iim.Element("name").Value;
          m.Vorname = iim.Element("vorname").Value;
          m.Gehalt = Double.Parse( iim.Element("Gehalt").Value);
          m.ID = Int32.Parse(iim.Element("id").Value);          
          vort.Add(m);
          IEnumerable<System.Xml.Linq.XElement> iKauf;
          iKauf = iim.Descendants("Kauf");
          foreach (System.Xml.Linq.XElement iik in iKauf)
          {
            Kauf k = new Kauf();
            k.Artikel= iik.Element("bez").Value;
            // weitere Datenübernahmen
            m.Add(k);
          }
        }
        ortliste.Add(vort);
      }
      return ortliste;
    }
  }
}

Das zurückgegebene Objekt hat in beiden Fällen dieselbe Struktur. Interessant sind die Varianten der Auwertung. Betrachten Sie zunächst die Arbeit über die Schnittstellenobjekte (jedes eingelesene Ort-Objekt wird über dessen Interface IOrt ansprechbar.


foreach (IOrt o in ReadXML(@"C:\wg\Ort_Elemente.xml"))
{
    Console.WriteLine(o);
    // Damit das funktioniert, 
    // muss das Interface IComparable implementiert sein
    // siehe Klasse Einwohner
    o.Einwohnerliste.Sort();
    foreach (IEinwohner xm in o.Einwohnerliste)
    {
        if(xm.Gehalt < 1000)
        {                    
            Console.WriteLine("\t{0} verdient {1:N2} Euro", xm, xm.Gehalt);
            //Hier könnten Sie noch weitermachen:
            //foreach (IKauf xk in xm.Kaufliste)
            //{
            //    Console.WriteLine("\t\t{0}", xk);
            //}
        }
    }
}

Die Alternative liegt in der Auwertung durch LINQ.


var vortliste = ReadXMLByLINQ((@"C:\wg\Ort_Elemente.xml"));
var vorte = from vort in vortliste
            orderby vort.Name ascending
            select vort;
foreach (var ort in vorte)
{
    Console.WriteLine("ID: {0}, Name: {1}", ort.ID, ort.Name);
    var vm = from v_m in ort.Einwohnerliste
                where v_m.Gehalt < 1000
                orderby v_m.Gehalt descending
                select v_m;
    foreach (var m in vm)
    {
        anzahl++;
        Console.WriteLine($"\t{m.Nachname} verdient {m.Gehalt} Euro");
    }
}

wg / 27. Januar 2019



Fragen? Anmerkungen? Tipps?

Bitte nehmen Sie Kontakt zu mir auf.






Vielen Dank für Ihr Interesse an meiner Arbeit.



V.i.S.d.P.: Wilfried Grupe * Klus 6 * 37643 Negenborn

☎ 0151. 750 360 61 * eMail: info10@wilfried-grupe.de

www.wilfried-grupe.de/cs_OOP_Interface_Ort_Mensch_Kauf.html