Verkettung von Erweiterungsmethoden in C #

7

Ist es möglich, eine Erweiterungsmethode zu erstellen, die die Instanz zurückgibt, die die Erweiterungsmethode aufruft?

Ich möchte eine Erweiterungsmethode für alles haben, was von ICollection<T> erbt, gibt das Objekt zurück. Ähnlich wie jQuery immer das jquery-Objekt zurückgibt.

%Vor%

Ich stelle mir etwas wie oben vor, aber ich bin mir nicht sicher, wie ich zum Objekttyp "this" zurückkommen soll, um etwas wie dieses zu verwenden:

%Vor%

EDIT: Ich wollte nur klarstellen, dass ich auf eine einzige generische Constraint-Lösung gehofft habe.

    
Mike_G 09.07.2010, 19:53
quelle

5 Antworten

13

Wenn Sie den spezifischen Typ zurückgeben müssen, können Sie eine generische Einschränkung verwenden:

%Vor%

Ich habe das getestet und es funktioniert in VS2010.

Update (bezüglich jQuery):

jQuery-Verkettung funktioniert sehr gut, da JavaScript dynamisches Schreiben verwendet. C # 4.0 unterstützt dynamic , also können Sie dies tun:

%Vor%

Ich empfehle jedoch die generische Constraint-Version, da sie typsicherer, effizienter ist und IntelliSense für den zurückgegebenen Typ zulässt. In komplexeren Szenarios können allgemeine Einschränkungen nicht immer das ausdrücken, was Sie benötigen. In diesen Fällen kann dynamic verwendet werden (obwohl es nicht an zusätzliche Erweiterungsmethoden bindet, funktioniert es also nicht gut mit der Verkettung).

    
Stephen Cleary 09.07.2010, 19:58
quelle
4

Obwohl ich VS nicht geöffnet habe, um dies zu versuchen, sollte etwas in diesen Zeilen funktionieren:

%Vor%     
Adam Robinson 09.07.2010 19:59
quelle
2

Sie haben anscheinend zwei widersprüchliche Ziele, und es kommt darauf an, was Ihre Erweiterungsmethode zurückgeben soll:

  • Die Instanz, die die Erweiterungsmethode (die Sammlung) aufgerufen hat
  • ODER das Element, das zur Sammlung hinzugefügt wurde

Aus Ihrer Beispielverwendung, hier zitiert:

%Vor%

Sie sehen so aus, als ob Sie die Sammlung zurückgeben möchten. In jedem Fall wird diese Zuweisung auch ohne eine Umwandlung nicht funktionieren, da Ihre Erweiterungsmethode einen Rückgabetyp der ICollection wie folgt haben müsste:

%Vor%

Das würde Ihnen erlauben, dies zu tun:

%Vor%

Wenn Sie nun das hinzugefügte Objekt zurückgeben möchten, sollten Sie immer noch keinen Rückgabetyp von object haben. Sie sollten Ihren generischen Typparameter nutzen und T wie folgt zurückgeben:

%Vor%

Wenn Sie jedoch das hinzugefügte Element zurückgeben, können Sie nicht wie folgt verketten:

%Vor%

, da der Rückgabetyp von AddItem(5) nicht ICollection ist, aber in diesem Fall T ( int ). Sie können jedoch immer noch verketten, direkt neben dem Mehrwert, wie folgt:

%Vor%

Es scheint so, als ob das erste Szenario nützlicher ist (Rückgabe der Sammlung), da es Ihnen ermöglicht, direkt an die ursprüngliche Zuweisungsanweisung zu ketten. Hier ist ein größeres Beispiel:

%Vor%

Oder, wenn Sie nicht casten möchten, können Sie ToList() auf der ICollection aufrufen, die zurückkommt:

%Vor%     
Samuel Meacham 09.07.2010 20:09
quelle
1
  

EDIT: Ich wollte nur klarstellen, dass ich auf eine einzige generische Constraint-Lösung gehofft habe.

In diesem Fall haben Sie kein Glück, da die Conversions der Rückgabetypen kovariant, aber nicht kontravariant sein können (dh Sie können nicht implizit von ICollection<T> in List<T> konvertieren), ohne einen generischen Rückgabetyp ist dies nicht möglich.

Was ist falsch bei der Angabe von 2 Typparametern? Sie können aus den Argumenten abgeleitet werden, die Sie der Funktion zur Verfügung stellen, so dass Sie sie in Ihrem Anrufcode nicht wirklich bemerken.

    
John Rasch 09.07.2010 20:13
quelle
0

Gib einfach ICollection<T> anstelle von object zurück und alles sollte so funktionieren, wie du es beabsichtigt hast.

    
Achim 09.07.2010 20:00
quelle