Advanced  Services Interfaces Back Next Up Home

Beispiel 1: Die klassische Implementierung

Die klassische Implementierung funktioniert wie in Java. Im folgenden Beispiel implementiert die Klasse Person das Interface System.IComparable. Generics werden dabei (noch) nicht verwendet.

 public class Person : IComparable
 {
     private string vorname;
     private string nachname;

     public Person() : this("","")
     {
     }

     public Person(string vor, string nach)
     {
         vorname = vor;
         nachname = nach;
     }

     public string NachName
     {
         get { return nachname; }
         set { nachname = value; }
     }

     public string VorName
     {
         get { return vorname; }
         set { vorname = value; }
     }


     // implementierung von CompareTo aus IComparable
     public int CompareTo(object ob)
     {
         if (ob is Person)
         {
            int erg = this.NachName.CompareTo(((Person)ob).NachName);
            return  erg!=0 ? erg : this.VorName.CompareTo(((Person)ob).VorName);
         }
         else throw new Exception("ubergebenes Object ist keine Person");
     }

 }  // end class Person

Ein Programm, das die Klasse verwendet kann wie üblich auf die Methode CompareTo zugreifen.

 class Program
 {
     static void Main(string[] args)
     {
         Person p1 = new Person("heinrich", "mann");
         Person p2 = new Person("thomas", "mann");

         int erg = p1.CompareTo(p2);
         Console.WriteLine(erg);  // ergebnis: -1
     }
 }

Beispiel 2: Die Implementierung mit Generics

Das Interface erhält den generischen Typ Person2. Vorteil: Aus einem RuntimeError wird so eine CompiletimeError.

 class Person : IComparable<Person>
 {
     private string vorname;
     private string nachname;

     public Person()
     {
         vorname = nachname = "";
     }

     public Person(string vname, string nname)
     {
         vorname = vname;
         nachname = nname;
     }

     public string Vorname
     {
         get { return vorname; }
         set { vorname = value; }
     }


     // implementierung von CompareTo aus IComparable
     public int CompareTo(Person pe)
     {
         int erg = this.nachname.CompareTo(pe.nachname);
         if (erg == 0)
                 return this.vorname.CompareTo(pe.vorname);
         return erg;
     }
 } // end class Person2

Ausschnitt aus einer Main-Methode:

string st = "hallo";

Person p = new Person("gustave", "flaubert");
//p.CompareTo(st);  // compilererror
//kann nicht von "string" in "Person2" konvertieren

Person p2 = new Person("anatole", "france");
int erg = p.CompareTo(p2);  // OK

Beispiel 3: Die explizite (aber versteckte) Implementierung (ohne Generics)

C# bietet eine weitere Möglichkeit an, eine Schnittstelle zu implementieren. Dabei wird der Name des Interfaces explizit übernommen. In dieser Version sind die Schlüsselwörter public und virtual nicht zulässig. Ihre Verwendung führt zu einer Fehlermeldung des Compilers.

 public class Person : IComparable
 {
     private string vorname;
     private string nachname;

     public Person()
         : this("", "")
     {
     }

     public Person(string vor, string nach)
     {
         vorname = vor;
         nachname = nach;
     }

     public string NachName
     {
         get { return nachname; }
         set { nachname = value; }
     }

     public string VorName
     {
         get { return vorname; }
         set { vorname = value; }
     }

     // public und virtual nicht erlaubt
     int IComparable.CompareTo(object ob)
     {
         int erg = this.NachName.CompareTo(((Person3)ob).NachName);
         return erg != 0 ? erg : this.VorName.CompareTo(((Person3)ob).VorName);
     }

 }  // end class Person

Als Folge davon ist eine Verwendung der Methode CompareTo wie im ersten Beispiel nicht möglich. Die Klasse Person3 kennt die Methode CompareTo nicht. Trotzdem kann man aber über einen kleinen Umweg die Methode aufrufen. über einen Cast zum Typ der Schnittstelle kann man die Methode dann doch verwenden.

class Program
{
   static void Main(string[] args)
   {
      Person p1 = new Person("heinrich", "mann");
      Person p2 = new Person("thomas", "mann");

      // p1.CompareTo(p2); Methode nicht bekannt

      IComparable c1 = p1;  // impliziter cast
      IComparable c2 = (IComparable)p2;  // expliziter cast

      int erg = c1.CompareTo(c2);
      Console.WriteLine(erg);  // -1
   }
}

Beispiel 4: Die explizite Implementierung mit Generics

Auch in diesem Beispiel sind die Schlüsselwörter public und virtual nicht zulässig. Außerdem muß bei der Implementierung der generische Typ abgegeben werden.

 class Person : IComparable<Person>
 {
     private string vorname;
     private string nachname;

     public Person()
     {
         vorname = nachname = "";
     }

     public Person(string vname, string nname)
     {
         vorname = vname;
         nachname = nname;
     }

     public string Vorname
     {
         get { return vorname; }
         set { vorname = value; }
     }

     // implementierung von CompareTo aus IComparable
     // generischer Typ  muß angegeben werden
     int IComparable<Person>.CompareTo(Person4 pe)
     {
         int erg = this.nachname.CompareTo(pe.nachname);
         if (erg == 0)
             return this.vorname.CompareTo(pe.vorname);
         return erg;
     }
 } // end class Person

Ausschnitt aus Main:

Person p = new Person("gustave", "flaubert");
// p.CompareTo(p); nicht bekannt
// aber
IComparable<Person> ic = (IComparable<Person>)p;  //
int erg = ic.CompareTo(p); // OK
Valid XHTML 1.0 Strict top Back Next Up Home