Für FuncT, TResult, wo A T erweitert, erfüllt A nicht für T

9

Okay, lassen Sie mich die Szene festlegen: Wir haben eine Funktion, die in unserem Code verwendet wird, die eine Funktion übernimmt und sie etwas protokolliert und dann das Ergebnis zurückgibt. Es sieht ein bisschen so aus.

%Vor%

Damit benutze ich die vier folgenden Objekte

%Vor%

Also, mit diesen versuche ich Mock LoggedApiCall (mit Moq), um einige Komponententests zu unterstützen. Ich schreibe eine generische Methode, die es uns ermöglicht, eine Funktion, die die Basistyp-Einschränkungen erfüllt, und eine Antwort, die auch Übereinstimmungen eingibt, zu übergeben, um eine allgemeine Methode zu erstellen, um .Setup () auf dem Mock auszuführen.

Es sieht so aus:

%Vor%

Der Grund, warum ich versuche, die Funktion zu erzeugen, ist, dass ich den IntelliSense-Fehler

bekomme, wenn ich das nicht tue %Vor%

Dies finde ich ein wenig verwirrend, da TRequest und TResponse wie durch BaseRequest bzw. BaseResponse eingeschränkt sind, aber wenn ich umherarbeiten muss, werde ich es tun. Allerdings, wenn Sie die Besetzung

durchführen %Vor%

es wird als null aufgelöst. Dies finde ich auch verwirrend aufgrund der oben erwähnten Einschränkungen für den Parameter, der an SetupLoggedApiCall übergeben wurde. Ich habe beim Debuggen des Codes noch etwas gegraben und folgendes bekommen:

%Vor%

Wie Sie sehen, erfüllt TResponse weiterhin BaseResponse und kann ohne Probleme in das System umgewandelt werden. Sobald wir jedoch versuchen, von TRequest zu BaseRequest zu wechseln, schlägt es fehl. Nur um sicher zu gehen, dass ich nicht in eine Situation geriet, in der irgendwelche falschen Typen oder irgendetwas importiert wurden, folgte ich uns mit:

%Vor%

Also, kann mir jemand sagen: Da alles darauf hinweist, dass TRequest ein BaseRequest ist, scheitert diese Besetzung an TRequest?

Wir werden damit beginnen, das Problem zu lösen und das Problem in einem neuen Code-Projekt zu isolieren (in Wirklichkeit ist unser Code nicht ganz so einfach wie unten, ich habe ihn vereinfacht) und sehe, an welchem ​​Punkt es ist scheitert und wir werden aktualisieren, wenn wir etwas finden, aber keine Einsicht würde geschätzt werden.

Update 1

Nachdem ich dem Vorschlag @EugenePodskal gefolgt habe, habe ich die Definition von LoggedApiCall aktualisiert, um

zu lesen %Vor%

Dies machte SetupLoggedApiCall glücklich, zumindest zur Kompilierzeit, da das, was übergeben wurde, gültig sein würde, der Aufruf des verspotteten Dienstes jedoch immernoch null zurückgibt. Ich grub zurück in das Proxy-Objekt und runter zum Interceptor für diesen Aufruf und ich entdeckte das:

%Vor%

Das ist kein Tippfehler. Der erste Parameter fehlt einfach im Interzeptor. Ich schätze, das verlagert die Frage mehr auf Mock als auf Func, aber da der Interceptor ein Lamba-Ausdruck ist, kann irgendjemand etwas erhellen, was dazu führen könnte, dass dieser Parameter einfach fehlt.

    
Kira Namida 21.10.2014, 09:42
quelle

1 Antwort

1

Das Thema, das Sie betrachten müssen, ist Covariance and Contravariance in Generics

Ссылка

d. "In .NET Framework 4 haben die allgemeinen Func-Delegaten, z. B. Func, kovariante Rückgabetypen und kontravariante Parametertypen."

Es ist auch logisch, wenn Sie darüber nachdenken ..

%Vor%

Daher sollten Sie für die Funktion parameter keine Umwandlung in den Basistyp zulassen.

Auf der anderen Seite, für Rückgabewerte , wenn die Funktion ursprünglich zur Rückgabe der Instanz von AppleProduct deklariert wurde, ist sie 100% (type) sicher und gibt eine Instanz von% co_de zurück % (Basisklasse für FuitProduct )

    
Vikas Gupta 31.10.2014 02:39
quelle

Tags und Links