Freigeben über


Stark typisierte Delegate

Vorhergehend

Im vorherigen Artikel haben Sie gesehen, dass Sie bestimmte Delegattypen mithilfe des delegate Schlüsselworts erstellen.

Die abstrakte Klasse für den Delegaten stellt die Infrastruktur für die lose Kopplung und den losen Aufruf bereit. Konkrete Delegattypen werden durch die Einführung und das Erzwingen von Typsicherheit für die Methoden, die zur Aufrufliste für ein Delegatobjekt hinzugefügt werden, viel nützlicher. Wenn Sie das delegate Schlüsselwort verwenden und einen konkreten Delegattyp definieren, generiert der Compiler diese Methoden.

In der Praxis würde dies dazu führen, dass neue Delegattypen erstellt werden, wenn Sie eine andere Methodensignatur benötigen. Diese Arbeit könnte nach einer Zeit mühsam werden. Jedes neue Feature erfordert neue Delegattypen.

Glücklicherweise ist dies nicht notwendig. Das .NET Core Framework enthält mehrere Typen, die Sie bei Bedarf von Stellvertretungstypen wiederverwenden können. Dies sind generische Definitionen, sodass Sie Anpassungen deklarieren können, wenn Sie neue Methodendeklarationen benötigen.

Der erste dieser Typen ist der Action Typ und mehrere Variationen:

public delegate void Action();
public delegate void Action<in T>(T arg);
public delegate void Action<in T1, in T2>(T1 arg1, T2 arg2);
// Other variations removed for brevity.

Der in Modifizierer für das generische Typargument wird im Artikel zur Kovarianz behandelt.

Es gibt Variationen des Action-Delegaten, der bis zu 16 Argumente enthält, wie z.B. Action<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16>. Es ist wichtig, dass diese Definitionen für jedes der Stellvertretungsargumente unterschiedliche generische Argumente verwenden: Dies bietet Ihnen maximale Flexibilität. Die Methodenargumente müssen nicht, aber möglicherweise derselbe Typ sein.

Verwenden Sie einen der Action-Typen für jeden Delegattyp, der über einen void-Rückgabetyp verfügt.

Das Framework enthält auch mehrere generische Delegattypen, die Sie für Delegattypen verwenden können, die Werte zurückgeben.

public delegate TResult Func<out TResult>();
public delegate TResult Func<in T1, out TResult>(T1 arg);
public delegate TResult Func<in T1, in T2, out TResult>(T1 arg1, T2 arg2);
// Other variations removed for brevity

Der out Modifizierer für das generische Ergebnistypargument wird im Artikel zur Kovarianz behandelt.

Es gibt Variationen des Func Delegaten mit bis zu 16 Eingabeargumenten, z. B. Func<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,TResult>. Der Typ des Ergebnisses ist immer der letzte Typparameter in allen Func Deklarationen nach Konvention.

Verwenden Sie einen der Func Typen für jeden Delegattyp, der einen Wert zurückgibt.

Es gibt auch einen speziellen Predicate<T> Typ für einen Delegat, der einen Test für einen einzelnen Wert zurückgibt:

public delegate bool Predicate<in T>(T obj);

Möglicherweise stellen Sie fest, dass für jeden Predicate Typ ein strukturell gleichwertiger Func Typ vorhanden ist. Beispiel:

Func<string, bool> TestForString;
Predicate<string> AnotherTestForString;

Sie können denken, dass diese beiden Typen gleichwertig sind. Das sind sie nicht. Diese beiden Variablen können nicht austauschbar verwendet werden. Eine Variable eines Typs kann dem anderen Typ nicht zugewiesen werden. Das C#-Typsystem verwendet die Namen der definierten Typen, nicht die Struktur.

All diese Stellvertretungstypdefinitionen in der .NET Core Library sollten bedeuten, dass Sie keinen neuen Delegattyp für jedes neue Feature definieren müssen, das Sie erstellen, für die Stellvertretungen erforderlich sind. Diese generischen Definitionen sollten alle Stellvertretungstypen bereitstellen, die Sie in den meisten Situationen benötigen. Sie können einfach einen dieser Typen mit den erforderlichen Typparametern instanziieren. Im Falle von Algorithmen, die generisch vorgenommen werden können, können diese Delegaten als generische Typen verwendet werden.

Dies sollte Zeit sparen und die Anzahl neuer Typen minimieren, die Sie erstellen müssen, um mit Stellvertretungen zu arbeiten.

Im nächsten Artikel werden mehrere gängige Muster für das Arbeiten mit Stellvertretungen in der Praxis angezeigt.

Nächster