C#2: Generics und IComparable


Thomas Wölfer
Thomas Wölfer

06. August 2005


Das meiner Ansicht nach wichtigste neue Feature in C# 2 sind 'Generics'. Dabei handelt es sich um ein Konstrukt das man wohl am besten mit den aus C++ bekannten Templates vergleicht, allerdings haben Generics und Templates doch einige wichtige Unterschiede. Darum soll es aber gerade nicht gehen - vielmehr wollte ich darauf eingehen, wie man in einer eigenen Klasse die Generics verwendet, mit dem operator== umzugehen hat.

Angenommen, man hat sowas:

class DependencyTracker<T>
{
   private List<T> dependencies = new List<T>();

   public AddDependency( Dependency<T> dp)
   {
       foreach( Dependency<T> d in dependencies)
       {
           if( d == dp) return; // fehler
       }
   }
}

Innerhalb der foreach-Schleife will man also abprüfen, das eine gegebene 'Dependency' nicht bereits in der Liste der Dependencies vorliegt. Der Compiler quittiert das aber mit einem Fehler - er hat nämlich keinerlei Möglichkeit sicherzustellen, das der Operator == für alle möglichen 'T' auch tatsächlich zur Verfügung steht.

Daher muss man selbiges sicherstellen, und das geht mit IComparable<T>:

class DependencyTracker<T> where T : IComparable<T>
// .... etc.

Angenommen, man will nun Dependencies von FooBars tracken, wobei FooBars ungefaehr so aussehen:

class foobar
{
    Guid guid:

    public foobar()
    {
        guid = Guid.NewGuid();
    }
}

Dazu muss man also irgendwo eine Dependey davon herstellen:

Dependecy<foobar> dep = new Dependency<foobar>();

Tut man das, und versucht dann 'dep' in den Tracker hinzuzufügen, dann gehts aber immer noch nicht, denn laut der eigenen Vereinbarung muss foobar IComparable<T> implementieren. Man braucht also folgendes (wobei die Implementierung hier einfach auf die Hilfe von Guid zurück greift:

class foobar : IComparable<foobar>
{
    Guid guid:

    public foobar()
    {
        guid = Guid.NewGuid();
    }

    public int CompareTo( foobar fb)
    {

         return guid.CompareTo( fb.guid);
    }
}