Nef*_*zen 33 c# delegates anonymous-methods
我不能成为唯一一个厌倦了定义和命名委托只需要一个需要委托的东西的人.例如,我想从可能的其他线程调用表单中的.Refresh(),所以我编写了这段代码:
private void RefreshForm()
{
if (InvokeRequired)
Invoke(new InvokeDelegate(Refresh));
else
Refresh();
}
Run Code Online (Sandbox Code Playgroud)
我甚至不确定我必须这样做,我只是读得足以害怕它在以后的某个阶段不起作用.
InvokeDelegate实际上是在另一个文件中声明的,但是我真的需要一个专门用于此的整个委托吗?根本没有任何通用代表?
我的意思是,例如,有一个Pen类,但也有Pens.选择笔,所以你不必重拍整个事情.它不一样,但我希望你理解我的意思.
skb*_*skb 52
是.在.NET 3.5中,您可以使用Func和Action委托.Func委托返回一个值,而Action委托返回void.以下是类型名称的外观:
System.Func<TReturn> // (no arg, with return value)
System.Func<T, TReturn> // (1 arg, with return value)
System.Func<T1, T2, TReturn> // (2 arg, with return value)
System.Func<T1, T2, T3, TReturn> // (3 arg, with return value)
System.Func<T1, T2, T3, T4, TReturn> // (4 arg, with return value)
System.Action // (no arg, no return value)
System.Action<T> // (1 arg, no return value)
System.Action<T1, T2> // (2 arg, no return value)
System.Action<T1, T2, T3> // (3 arg, no return value)
System.Action<T1, T2, T3, T4> // (4 arg, no return value)
Run Code Online (Sandbox Code Playgroud)
我不知道他们为什么每次停在4个args,但对我来说一直都足够了.
Eri*_*bes 26
您可以使用Action委托,如下所示:
private void RefreshForm()
{
if (InvokeRequired) Invoke(new Action(Refresh));
else Refresh();
}
Run Code Online (Sandbox Code Playgroud)
或者,使用lambda语法:
private void RefreshForm()
{
if (InvokeRequired) Invoke((Action)(() => Refresh()));
else Refresh();
}
Run Code Online (Sandbox Code Playgroud)
最后是匿名委托语法:
private void RefreshForm()
{
if (InvokeRequired) Invoke((Action)(delegate { Refresh(); }));
else Refresh();
}
Run Code Online (Sandbox Code Playgroud)
在这种特定情况下,您可以(并且应该)只使用MethodInvoker来执行此操作...这就是它存在的原因.
if (InvokeRequired)
Invoke(new MethodInvoker(Refresh));
else
Refresh();
Run Code Online (Sandbox Code Playgroud)
如果你正在做其他事情你可以,正如其他人已经回答使用Func <T,...>或Action <T,...>如果它们适合你的用例.
精简版:
Invoke((MethodInvoker)delegate { Refresh(); });
Run Code Online (Sandbox Code Playgroud)
然后你也可以去掉 InvokeRequired 的检查;你可以直接调用它。如果您需要传递参数,也可以使用,因此不需要其他特定于参数的委托(也适用于无参数的 Action 委托):
private void SetControlText(Control ctl, string text)
{
Invoke((MethodInvoker)delegate { ctl.Text = text; });
}
Run Code Online (Sandbox Code Playgroud)