I have this general function to invoke a WinForm control:
public static void Invoke(this Control c, Action action)
{
if (c.InvokeRequired)
c.TopLevelControl.Invoke(action);
else
action();
}
I'm thinking of making it better by bringing harsher constraints to prevent things that are meaningless, may be like:
button1.Invoke(() => list.Add(1));
Also there can be redundant typing like:
button1.Invoke(() => button1.Hide());
since we are already specifying the this
is button1
.
So I made it:
public static void Invoke<T>(this T c, Action<T> action) where T : Control
{
if (c.InvokeRequired)
c.TopLevelControl.Invoke(action);
else
action(c);
}
Now I'll have to call,
button1.Invoke((c) => c.Hide());
or
button1.Invoke((c) => button1.Hide());
Now I kind of feel that even then there is some more than required typing. If I'm specifying this
is button1
, then in the lambda expression I do not want to specify a dummy variable c
again to tell where to operate on. Is there anyway I can make this shorter again? Perhaps like
button1.Invoke(Hide);
or
button1.Hide.Invoke();
or so in C#?
First let me say that you may be overthinking this - short code is a great thing, but there's a point where it starts to be confusing for anyone attempting to read the code.
Now, your first suggestion:
button1.Invoke(Hide);
could work, if you make it:
button1.Invoke(button1.Hide);
because otherwise the compiler cannot know, where to look for the method Hide(). It could even cause some weird behavior, for example if all of this code was in some derived class, like this:
class A : Control {
public A() {
Button button1=new Button();
button1.Invoke(Hide);
}
}
Now it would compile, but the Hide() method would be the Hide() method of whole control, not the button! The way to achive this is simply:
public static void Invoke(this Control c, Action action) {
c.Invoke(action);
}
The latter way:
button1.Hide().Invoke();
would work even without adding extension methods, you just need to make it:
((Action)button1.Hide).Invoke();
This of course means the Hide() method gets invoked in the current thread, which is probably not what you want. So make it:
((Action)button1.Hide).Invoke(button1);
public static void Invoke(this Action action, Control c) {
c.Invoke(action);
}
Sorry for long answer, hope it helps.