Advanced Services | Interfaces |
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 } }
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
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 } }
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