Frage

Ich bin neu in alle anonymen Funktionen und benötige Hilfe. Ich habe folgendes bekommen zu arbeiten:

public void FakeSaveWithMessage(Transaction t)
{
    t.Message = "I drink goats blood";
}

public delegate void FakeSave(Transaction t);

public void SampleTestFunction()
{
    Expect.Call(delegate { _dao.Save(t); }).Do(new FakeSave(FakeSaveWithMessage));
}

Das ist aber total hässlich, und ich möchte das Innere des Do habe eine anonyme Methode oder auch ein Lambda sein, wenn es möglich ist. Ich habe versucht:

Expect.Call(delegate { _dao.Save(t); }).Do(delegate(Transaction t2) { t2.Message = "I drink goats blood"; });

und

Expect.Call(delegate { _dao.Save(t); }).Do(delegate { t.Message = "I drink goats blood"; });

aber diese geben mir

  

Kann nicht anonyme Methode konvertieren ‚System.Delegate‘ zu geben, weil es kein Delegattyp ist ** Fehler kompiliert werden.

Was mache ich falsch?


Aufgrund dessen, was Mark Ingram geschrieben, scheint die beste Antwort, wenn auch niemand gesagt, es ausdrücklich, ist dies zu tun:

public delegate void FakeSave(Transaction t);

Expect.Call(delegate { _dao.Save(t); }).Do( new FakeSave(delegate(Transaction t2) { t.Message = expected_msg; }));
War es hilfreich?

Lösung

Das ist eine bekannte Fehlermeldung. Überprüfen Sie den folgenden Link für eine ausführlichere Diskussion.

http: // staceyw1 .wordpress.com / 2007/12/22 / sie-sind-anonymous-Methoden-nicht-anonymen-Delegierten /

Im Grunde brauchen Sie nur eine Besetzung vor Ihrem anonymen Delegaten setzen (Ihr Lambda-Ausdruck).

die Verbindung überhaupt Bei geht, ist hier eine Kopie der Post:

  

Sie sind Anonyme Methoden, nicht   Anonymous Delegierten.
  Veröffentlicht am 22. Dezember 2007 von staceyw1

     

Es ist nicht nur ein Gesprächsthema, denn   wir wollen, schwierig sein. Es hilft uns,   Grund zu wissen, was genau vor sich geht.   Um klar zu sein, gibt es nicht so etwas *   als anonymer Delegierter. Sie tun es nicht   existiert (noch nicht). Sie sind „Anonymous   Methods“- Periode Es spielt eine Rolle in wie.   wir von ihnen denken und wie wir sprechen über   Sie. Werfen wir einen Blick auf die   anonyme Methode Anweisung „delegieren ()   {...}“. Das ist eigentlich zwei verschiedene   Operationen und wenn wir denken an sie   Auf diese Weise werden wir nie verwechselt werden   nochmal. Das erste, was der Compiler   tut, ist die anonyme Methode erstellen   unter der Decke unter Verwendung der abgeleiteten   Signatur als Verfahren delegieren   Unterschrift. Es ist nicht richtig zu sagen,   das Verfahren ist „unnamed“, weil es   hat einen Namen und den Compiler   ordnet sie. Es ist nur versteckt aus   normale Ansicht. Das nächste, was es tut   ein Delegatobjekt der ist erstellen   erforderliche Art des Verfahrens zu wickeln. Diese   Delegierte Inferenz und kann aufgerufen   die Quelle dieser Verwirrung. Zum   dies funktioniert, muss der Compiler sein   Lage, herauszufinden, (d infer), was   Delegattyp wird es schaffen. Es hat   ein bekannter konkreter zu sein. Lassen   schreiben einige Code, um zu sehen, warum.

private void MyMethod()
{
}
  

Ist nicht kompilieren:

1) Delegate d = delegate() { };                       // Cannot convert anonymous method to type ‘System.Delegate’ because it is not a delegate type
2) Delegate d2 = MyMethod;                         // Cannot convert method group ‘MyMethod’ to non-delegate type ‘System.Delegate’
3) Delegate d3 = (WaitCallback)MyMethod;   // No overload for ‘MyMethod’ matches delegate ‘System.Threading.WaitCallback’
  

Zeile 1 nicht kompiliert, da die   Compiler kann keine Delegierten schließen   Art. Es kann deutlich die Unterschrift sehen   wir wünschen, aber es gibt keine konkreten   Geben Sie delegieren kann der Compiler sehen.   Es könnte eine anonyme Art von erstellen   Geben Sie Delegat für uns, aber es funktioniert nicht   wie das funktioniert. Linie 2 nicht   kompilieren aus einem ähnlichen Grund. Sogar   obwohl weiß der Compiler die Methode   Unterschrift, wir geben es nicht   Typ delegieren und es ist nicht nur gehen   um eine auswählen, die funktionieren würde passieren   (Nicht, welche Nebenwirkungen das könnte   haben). Linie 3 nicht, weil Arbeit   wir nicht übereinstimmen absichtlich die Methode   Signatur mit einem Delegieren einer mit   andere Signatur (als WaitCallback   nimmt und Objekt).

     

Kompiliert:

4) Delegate d4 = (MethodInvoker)MyMethod;  // Works because we cast to a delegate type of the same signature.
5) Delegate d5 = (Action)delegate { };              // Works for same reason as d4.
6) Action d6 = MyMethod;                                // Delegate inference at work here. New Action delegate is created and assigned.
  

Im Gegensatz dazu diese Arbeit. Zeile 1 Werk   weil wir sagen dem Compiler was   delegieren Typ zu verwenden und sie übereinstimmen,   so dass es funktioniert. Linie 5 arbeitet für die   gleicher Grund. Beachten wir die besondere verwendet   Form „delegieren“ ohne die Pars.   Der Compiler folgert das Verfahren   Unterschrift von der Besetzung und schafft   die anonyme Methode mit dem gleichen   Signatur als die abgeleiteten Delegierten   Art. Line 6 funktioniert, weil die   MyMethod () und Aktion verwenden gleiche   Unterschrift.

     

Ich hoffe, das hilft.

     

Siehe auch:    http://msdn.microsoft.com/msdnmag/issues/04/05/ C20 /

Andere Tipps

Was Mark sagte.

Das Problem ist, dass Do einen Delegierten Parameter annimmt. Der Compiler kann nicht die anonymen Methoden konvertieren zu delegieren, nur einen „Delegattyp“ heißt konkreter von Delegierten abgeleitet.

Wenn die Do-Funktion Aktion hatte die <>, Aktion <,> ... usw. Überlastungen, würden Sie nicht die Besetzung müssen.

Das Problem ist nicht mit Ihrem Delegat Definition, dann ist es, dass der Parameter des Do () Methode des Typs System.Delegate ist, und der Compiler generiert Delegattyp (FakeSave) konvertiert nicht implizit System.Delegate.

Versuchen Sie, eine Guss vor Ihrem anonymen Delegaten hinzu:

Expect.Call(delegate { _dao.Save(t); }).Do((Delegate)delegate { t.Message = "I drink goats blood"; });

Versuchen Sie so etwas wie:

Expect.Call(delegate { _dao.Save(t); }).Do(new EventHandler(delegate(Transaction t2) { t2.CheckInInfo.CheckInMessage = "I drink goats blood"; }));

Beachten Sie die zusätzlichen Eventhandler um die Delegierten.

EDIT:. Könnte nicht funktionieren, da die Funktion Unterschriften von Eventhandler und den Delegierten nicht gleich sind ... Die Lösung, die Sie auf der Unterseite Ihrer Frage hinzugefügt werden, der einzige Weg sein

Alternativ können Sie einen allgemeinen Delegattyp erstellen:

public delegate void UnitTestingDelegate<T>(T thing);

Damit die Delegierten nicht Transaktion spezifisch ist.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top