Implicitly convert a group of methods to a delegate (for the argument Control.Invoke)

I am working on a Windows Forms application and contains custom controls with methods that could potentially be called from threads other than a UI thread. Therefore, these methods look a bit to exclude exceptions:

public void DoSomeStuff() { if (InvokeRequired) { Invoke((Action)DoSomeStuff); } else { // Actually do some stuff. } } 

The explicit involvement of the DoSomeStuff group of methods in Action attracted my attention, and so I studied delegates and other related topics more deeply than before.

Although I saw some related questions, I could not find the exact answer to my question:

Why in this case, the DoSomeStuff method DoSomeStuff requires an explicit cast to Action ?

If I remove the cast, then I get two errors:

Error 102 Argument 1: Cannot convert from 'method group' to 'System.Delegate'

Error 101 The best overloaded method match for 'System.Windows.Forms.Control.Invoke (System.Delegate, params object [])' has some invalid arguments

The fact that the compiler seems to be confused about which overload of Invoke to use seems like a pretty big hint, but I'm still not sure why this can't figure it out. I expect the compiler to deduce that the first Invoke overload, which takes one Delegate argument, is the one that should be used.

I would expect, because there is no problem if the code is written as follows:

 Action a = DoSomeStuff; Invoke(a); 

The DoSomeStuff method DoSomeStuff can be implicitly converted to the Action delegate type, and Action outputs (technically?) From System.Delegate , so Invoke can handle the argument a without any problems. But then why can't the implicit conversion be done by the compiler when I try to pass the DoSomeStuff as an argument directly? Honestly, I'm not convinced of my logic here, but I'm still not sure what I am missing.

+6
source share
1 answer

The problem is not that the compiler has problems with overloading. The “best match” overload is the one you want but has the wrong arguments. C # does not define any implicit conversion from a group of methods ( DoSomeStuff ) to System.Delegate .

We can say that the compiler should simply select one of the Action / Func types, and this was requested as a function of the language. Now this is not part of C #. (I don’t know why, I hope that the request for the language will pass.)

System.Windows.Forms.Control.Invoke was created in .NET 1.0. Today you can use the following signatures:

 void Invoke(Action action); Task InvokeAsync(Action action); 

And it will just work.

Try switching to await and this ceases to be a problem.

+2
source

All Articles