Wir haben eine generische Erweiterungsmethode, die nur für Objekte funktioniert, die sowohl die INotifyCollectionChanged- als auch die IEnumerable-Schnittstelle unterstützen. Es ist so geschrieben:
%Vor% Das folgende kompiliert gut, da ObservableCollection<string>
beide Schnittstellen implementiert und dank des Schlüsselworts 'var' ist typedType stark typisiert:
Wir versuchen dies jedoch von einem ValueConverter aus aufzurufen. Das Problem ist, dass der eingehende Wert vom Typ object
ist und obwohl wir testen können, dass das übergebene Objekt beide Schnittstellen implementiert, können wir nicht herausfinden, wie wir es explizit umwandeln können, damit wir diese generische Erweiterungsmethode aufrufen können. Dies funktioniert nicht (offensichtlich) ...
Wie können Sie also ein Objekt auf mehrere Interfaces umwandeln, damit Sie das generische Objekt aufrufen können? Nicht einmal sicher, dass es möglich ist.
Der sauberste Weg, den ich mir vorstellen kann, wäre dynamic
. Da Erweiterungsmethoden jedoch nicht mit dynamic
(siehe bleich) funktionieren, müssen Sie explizit auf die Erweiterungsmethode verweisen.
BEARBEITEN Als Hinweis auf die Frage, auf die ich hier hingewiesen habe, ist zu beachten, dass der Aufruf der Methode mit explizitem dyanmic
als Typargument (über DoSomething<dynamic>
) nicht Arbeit - es verursacht Kompilierungsfehler, wenn versucht wird, mit mehreren Einschränkungen übereinzustimmen. Wenn nicht mehrere Integritätsbedingungen verwendet werden, führt dies dazu, dass dynamic
basierend auf dem Kompilierungszeittyp der übergebenen Variablen, nicht dem Laufzeittyp aufgelöst wird.
Dies führt zu einem Aufruf von Extensions.UnknownType<dynamic>
, dessen dynamic
zur Laufzeit aufgelöst wird - was bedeutet, dass der vollständig abgeleitete Typ des angegebenen Parameters verwendet wird. Solange dieser Parameter die gewünschten Schnittstellen implementiert, gehen Sie los.
Seien Sie vorsichtig, da es wie bei dynamic
code zu Problemen kommen kann, die erst zur Laufzeit erkannt werden. Verwenden Sie sparsam!
Wenn Sie mehrere Aufrufe mit denselben generischen Parametern durchführen, sollten Sie eine generische Hilfsmethode in Ihrem Konverter hinzufügen und dann das mit value as dynamic
Zusatz :
Bei der Verwendung von dynamic
versucht alles, was gegen das Objekt dynamic
aufgerufen wird, zur Laufzeit als Element des angegebenen Typs aufgelöst zu werden. nicht sucht nach Erweiterungsmethoden, da sie inhärent existieren in einer ganz anderen Klasse, oft eine andere Versammlung.
Sie können versuchen, mithilfe von MethodInfo und delegates einen Delegaten für die richtige Methode abzurufen.
Die folgende Lösung verwendet nicht dynamic , sondern ein wenig Reflection . Grundsätzlich führt die Methode die folgenden Operationen durch:
Die _Placeholder -Klasse ist der bekannte Typ, der zum Abrufen des anfänglichen Delegaten verwendet wird, Sie können jedoch jeden anderen Typ verwenden, der die generischen Einschränkungen erfüllt.
Auf diese Weise haben Sie auch die Möglichkeit, den Namen der Erweiterungsmethode und ihre Einschränkungen zu überprüfen.
Ein guter Ansatz würde auch das endgültige MethodInfo (oder Delegate) zwischenspeichern, um zu vermeiden, teure Anrufe zu wiederholen.
%Vor%