Warum ist diese Frage das erste Ergebnis in Google bei der Suche nach dem Fehler "Anonyme Funktion, die in einen ungültig zurückgegebenen Delegaten konvertiert wurde, kann keinen Wert zurückgeben", wenn sie eindeutig nichts damit zu tun hat?
Calmarius
Antworten:
134
Das Problem hierbei ist, dass Sie eine anonyme Methode definiert haben, die a zurückgibt, stringaber versucht, sie direkt a zuzuweisen string. Es ist ein Ausdruck, der beim Aufrufen ein stringnicht direktes a erzeugt string. Es muss einem kompatiblen Delegatentyp zugewiesen werden. In diesem Fall ist die einfachste WahlFunc<string>
Func<string> temp =()=>{return"test";};
Dies kann in einer Zeile durch ein wenig Casting oder mithilfe des Delegate-Konstruktors erfolgen, um den Typ des Lambda zu bestimmen, gefolgt von einem Aufruf.
Vielen Dank. Also keine Möglichkeit, alles in einer Zeile zu erledigen (einschließlich der Zuweisung von Zeichenfolgen)? Der Wert, den ich möchte ("Test", der im wirklichen Leben tatsächlich eine Variable ist), befindet sich in einem anderen Lambda, sodass ich den Umfang verliere, wenn ich versuche, wie oben definiert zu definieren.
4. Raum
@ 4thSpace kann mit bösem Casting in einer Zeile ausgeführt werden. Ich habe meine Antwort aktualisiert, um den Weg zu zeigen
JaredPar
Oder in diesem Fall einfach Func<string> temp = () => "test";.
Gabe
Oder im Falle Ihrer Bearbeitungstring temp = new Func<string>(() => "test")();
Gabe
Perfekt! Wenn ich ein int übergeben wollte, können Sie das in einer Zeile zeigen? Ich habe es versucht, aber es geht nicht: ((Func <int, string>) ((4) => {return "test";})) ();
4. Raum
15
Sie versuchen , einem Zeichenfolgentyp einen Funktionsdelegierten zuzuweisen . Versuche dies:
Func<string> temp =()=>{return"test";};
Sie können die Funktion nun folgendermaßen ausführen:
Interessante Technik. Fügt dies den Laufzeitaufwand hinzu oder ist alles zur Kompilierungszeit?
ToolmakerSteve
@ToolmakerSteve: Ich vermute, dass dadurch ein wenig Laufzeitaufwand entsteht (ein Aufruf einer anonymen Methode wird in eine andere Methode eingeschlossen). Ich vermute jedoch, dass dies auch davon abhängt, wo die FuncInvoke-Methode definiert wurde (dieselbe Assembly wie wo) Es wird gegen verschiedene Assemblys usw. aufgerufen, da es die Art von Dingen sein könnte , die der Compiler "inline" machen könnte. Dies ist die Art von Frage, die die Leute beantworten, indem sie ein schnelles Testprogramm schreiben, kompilieren und dann die resultierende IL auseinander nehmen.
Daniel Scott
@ToolmakerSteve Nach dieser letzten "Vermutung" der Auswirkungen auf die Leistung würde ich hinzufügen, dass selbst die schlimmsten Auswirkungen auf die Leistung praktisch null wären (ein zusätzlicher Funktionsaufruf für eine nicht virtuelle, statische Methode). Jeder, der diese Technik anwendet, tut dies wahrscheinlich, weil er Lambdas herumwirft. Das bedeutet, dass sie wahrscheinlich irgendwo mindestens ein paar LINQ-Erweiterungsmethoden verwenden. Die Chancen stehen also gut, dass sie versehentlich ein paar LINQ-Methoden so verkettet haben, dass die Leistung 100.000-mal schlechter ist als bei einem zusätzlichen Funktionsaufruf ;)
Daniel Scott
5
Sie können eine anonyme Methode mit Argument verwenden:
int arg =5;string temp =((Func<int,string>)((a)=>{return a ==5?"correct":"not correct";}))(arg);
Sie können, aber bitte erklären Sie, wie dies eine Antwort auf die Frage ist.
ToolmakerSteve
2
Eine anonyme Methode kann mithilfe eines func-Delegaten einen Wert zurückgeben. Hier ist ein Beispiel, in dem ich gezeigt habe, wie ein Wert mit einer anonymen Methode zurückgegeben wird.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp1{classProgram{staticvoidMain(string[] args){Func<int,int> del =delegate(int x){return x * x;};int p= del(4);Console.WriteLine(p);Console.ReadLine();}}}
Dies ist ein weiteres Beispiel für die Verwendung von C # 8 ( könnte auch mit anderen .NET-Versionen funktionieren, die parallele Aufgaben unterstützen ).
using System;
using System.Threading.Tasks;
namespace Exercise_1_Creating_and_Sharing_Tasks{internalstaticclassProgram{privatestaticintTextLength(object o){Console.WriteLine($"Task with id {Task.CurrentId} processing object {o}");return o.ToString().Length;}privatestaticvoidMain(){conststring text1 ="Welcome";conststring text2 ="Hello";var task1 =newTask<int>(()=>TextLength(text1));
task1.Start();var task2 =Task.Factory.StartNew(TextLength, text2);Console.WriteLine($"Length of '{text1}' is {task1.Result}");Console.WriteLine($"Length of '{text2}' is {task2.Result}");Console.WriteLine("Main program done");Console.ReadKey();}}}
Antworten:
Das Problem hierbei ist, dass Sie eine anonyme Methode definiert haben, die a zurückgibt,
string
aber versucht, sie direkt a zuzuweisenstring
. Es ist ein Ausdruck, der beim Aufrufen einstring
nicht direktes a erzeugtstring
. Es muss einem kompatiblen Delegatentyp zugewiesen werden. In diesem Fall ist die einfachste WahlFunc<string>
Dies kann in einer Zeile durch ein wenig Casting oder mithilfe des Delegate-Konstruktors erfolgen, um den Typ des Lambda zu bestimmen, gefolgt von einem Aufruf.
Hinweis: Beide Beispiele könnten mit der Ausdrucksform kurzgeschlossen werden, der das fehlt
{ return ... }
quelle
Func<string> temp = () => "test";
.string temp = new Func<string>(() => "test")();
Sie versuchen , einem Zeichenfolgentyp einen Funktionsdelegierten zuzuweisen . Versuche dies:
Sie können die Funktion nun folgendermaßen ausführen:
Die Variable "s" hat jetzt den Wert "test".
quelle
Mit ein wenig Hilfsfunktion und Generika können Sie den Compiler auf den Typ schließen lassen und ihn ein wenig verkürzen:
Randnotiz: Dies ist auch schön, da Sie dann einen anonymen Typ zurückgeben können:
quelle
Sie können eine anonyme Methode mit Argument verwenden:
quelle
Eine anonyme Methode kann mithilfe eines func-Delegaten einen Wert zurückgeben. Hier ist ein Beispiel, in dem ich gezeigt habe, wie ein Wert mit einer anonymen Methode zurückgegeben wird.
quelle
Dies ist ein weiteres Beispiel für die Verwendung von C # 8 ( könnte auch mit anderen .NET-Versionen funktionieren, die parallele Aufgaben unterstützen ).
quelle