Ich arbeite an einer Windows Forms-Anwendung, und es enthält benutzerdefinierte Steuerelemente mit Methoden, die potenziell von anderen Threads als dem UI-Thread aufgerufen werden können. So also diese Methoden ein wenig aussehen wie diese Ausnahmen zu verhindern:Konvertieren Sie implizit Methodengruppe in Delegat (für Argument von Control.Invoke)
public void DoSomeStuff()
{
if (InvokeRequired)
{
Invoke((Action)DoSomeStuff);
}
else
{
// Actually do some stuff.
}
}
Die explizite Umwandlung der Methodengruppe DoSomeStuff
zu einem Action
meine Aufmerksamkeit erregt, und so habe ich gesucht, in Delegierte und andere verwandte Themen tiefer als ich vorher habe.
Obwohl ich einige Fragen hier gesehen habe, habe ich nicht in der Lage gewesen, genau die Antwort auf meinen finden, das ist:
Warum wird die Methodengruppe DoSomeStuff
explizite Umwandlung erfordert ein Action
in diesem Fall?
Wenn ich die Besetzung zu entfernen, dann bekomme ich zwei Fehler:
Fehler 102 Argument 1: kann nicht von 'Methodengruppe' zu
'System.Delegate' konvertierenError 101 Die besten überladene Methode Übereinstimmung für 'System.Windows.Forms.Control.Invoke (System.Delegate, params Objekt [])' hat einige ungültige Argumente
The Tatsache, dass der Compiler anscheinend verwirrt ist, welche Überladung von Invoke
zu verwenden scheint wie ein ziemlich großer Hinweis, aber ich bin mir immer noch nicht sicher, warum genau das nicht herausfinden kann. Ich würde erwarten, dass der Compiler daraus folgert, dass die erste Überladung von Invoke
, die ein einzelnes Delegate
-Argument benötigt, diejenige ist, die verwendet werden sollte.
Ich würde erwarten, dass, weil es kein Problem, wenn der Code wie folgt geschrieben:
Action a = DoSomeStuff;
Invoke(a);
Die Methodengruppe DoSomeStuff
kann implizit in den Action
Delegattyp umgewandelt werden, und Action
herleitet (technisch?) Aus System.Delegate
, also Invoke
kann das Argument a
ohne Probleme behandeln. Aber warum kann die implizite Konvertierung nicht vom Compiler ausgeführt werden, wenn ich versuche, DoSomeStuff
als Argument direkt zu übergeben? Um ehrlich zu sein, bin ich nicht von meiner eigenen Logik überzeugt, aber ich bin mir immer noch nicht sicher, was ich vermisse.
> Sie könnten sagen, dass der Compiler nur einen der Action/Func-Typen auswählen sollte und dies als Sprachfeature angefordert wurde Dies zerfällt sehr leicht: 'void Foo (out string abc);' Ist nicht darstellbar mit 'Action' oder' Func'. Wenn sie Action/Func-Inferenz als Sprachfeature implementieren, wäre diese Funktion kaputt. – GeirGrusom
@GeirGrusom Mit dieser speziellen Signatur könnte die Konvertierung fehlschlagen (statisch). Es ist ein seltener Fall, ich denke, es ist in Ordnung, hier einen Fehler zu zeigen. Nicht jede Methode kann als Action/Func dargestellt werden, aber 99% davon können in der Praxis sein. Alle Delegattypen sollten strukturell mit impliziten Konvertierungen behandelt werden, wenn dies sinnvoll ist. – usr
Ich glaube nicht, dass es in Ordnung ist. Der Fehler wird angezeigt, da das Feature grundlegend beschädigt ist. – GeirGrusom