Tipps und Tricks rund um .NET und Visual Studio

Sprachsyntax C Contravarianz
Kommentare

Dr. Holger Schwichtenberg (MVP) und FH-Prof. Manfred Steyer teilen in der Kolumne „.NETversum“ ihr Expertenwissen rund um .NET-Tools und WPF mit.

Ähnlich wie das Schlüsselwort out seit C# 4.0 dazu führt, dass Typparameter nur für Rückgabewerte und out-Parameter verwendet werden dürfen, stellt in sicher, dass sie lediglich für Übergabeparameter herangezogen werden dürfen. Warum auch das ab und an Sinn macht, zeigen die nächsten Zeilen. Listing 1 zeigt eine Klasse Tier sowie eine Klasse Hamster, die von Tier erbt. Danach wird eine Klasse TierComparer deklariert, die IComparer implementiert. Implementierungen von IComparer werden verwendet, um zwei Instanzen eines Typs in Hinblick auf eine bestimmte Reihenfolge, meist im Zuge eines Sortiervorgangs, zu vergleichen. Die durch dieses Interface vorgegebene Methode Compare nimmt zwei Instanzen entgegen und liefert per Definition einen negativen Wert, wenn die erste Instanz kleiner als die zweite ist. Ist die zweite Instanz größer als die erste, wird ein positiver Wert geliefert; bei Gleichheit Null (0). In der danach dargestellten Methode ContraVariance wird eine Liste mit zwei Hamstern sowie eine Instanz von TierComparer erstellt. Um die Liste mit diesem Comparer zu sortieren, wird er nach IComparer gecastet und an die Methode Sort der Liste übergeben. Der Cast wird dabei nur durchgeführt, um anzudeuten, dass Sort in diesem Fall einen IComparer erwartet.

Listing 1

class Tier {
public int Id { get; set; }
public String Name { get; set; }
}

class Hamster : Tier {
public void LaufeImRad() { }
}

class TierComparer : IComparer
{
public int Compare(Tier x, Tier y)
    {
if (x.Id < y.Id) return -1;
if (x.Id > y.Id) return 1;
return 0;
    }
}
[...]
private static void ContraVariance()
{
Hamster h1 = new Hamster() { Name = "Krümel" };
Hamster h2 = new Hamster() { Name = "Goldy" };

List kaefig = new List() { h1, h2 };
TierComparer tierComparer = new TierComparer();
IComparer comparer = tierComparer;
kaefig.Sort(comparer);
}  

Somit werden Hamster mit einem TierComparer sortiert, der IComparer implementiert und innerhalb von Sort als IComparer angesprochen wird. Da ein Hamster auch ein Tier ist, scheint das kein Problem zu sein. Vor C# 4.0 wäre der dazu nötige Cast von IComparer auf IComparer jedoch nicht möglich gewesen, denn das würde ja bedeuten, dass Methoden, von denen erwartet wird, dass sie einen Hamster zurückliefern, stattdessen irgendein Tier, zum Beispiel ein Krokodil, zurückliefern. Das wäre jedoch im Sinne der Typsicherheit nicht korrekt. In Fällen, in denen ein Typparameter, wie im Fall von IComparer<... >, lediglich für Übergabeparameter und nicht für Rückgabewerte verwendet wird, ist diese Befürchtung jedoch bedenkenlos. Ab C# 4.0 können solche Fälle berücksichtigt werden, indem mit dem Schlüsselwort in für Typparameter in Interfaces oder Delegates angegeben wird, dass sie nur für Übergabeparameter verwendet werden dürfen. Das integrierte Interface IComparer<...> macht von dieser Möglichkeit ab .NET 4.0 Gebrauch. Das ist auch der Grund dafür, dass dieses Beispiel mit C# 4.0 funktioniert. Das folgende Beispiel zeigt die Verwendung von in anhand dieses in .NET 4.0 enthaltenen Interface:

public interface IComparer
{
Compare(T x, T y);
}  

Dr. Holger Schwichtenberg (MVP) und FH-Prof. Manfred Steyer arbeiten bei www.IT-Visions.de als Softwarearchitekten, Berater und Trainer für .NET-Technologien. Dabei unterstützen sie zahlreiche Unternehmen beim Einsatz von .NET und entwickeln selbst in größeren Projekten. Sie haben zahlreiche Fachbücher geschrieben und gehören seit vielen Jahren zu den Hauptsprechern auf der BASTA!. Manfred Steyer ist zudem für den Fachbereich „Software Engineering“ der Studienrichtung „IT und Wirtschaftsinformatik“ an der FH CAMPUS 02 in Graz verantwortlich. Dr. Holger Schwichtenberg unterrichtet in Lehraufträgen an den Fachhochschulen Münster und Graz.
Unsere Redaktion empfiehlt:

Relevante Beiträge

Meinungen zu diesem Beitrag

X
- Gib Deinen Standort ein -
- or -