C#中的匿名委托
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/978063/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
anonymous delegates in C#
提问by Nefzen
I can't be the only one getting tired of defining and naming a delegate for just a single call to something that requires a delegate. For example, I wanted to call .Refresh() in a form from possibly other threads, so I wrote this code:
我不可能是唯一一个厌倦了为需要委托的事物定义和命名委托的人。例如,我想以其他线程的形式调用 .Refresh(),因此我编写了以下代码:
private void RefreshForm()
{
if (InvokeRequired)
Invoke(new InvokeDelegate(Refresh));
else
Refresh();
}
I'm not even sure I have to, I just read enough to be scared that it won't work at some later stage.
InvokeDelegate is actually declared in another file, but do I reallyneed an entire delegate dedicated just for this? aren't there any generic delegates at all?
I mean, for example, there's a Pen class, but there's also Pens.pen-of-choiceso you don't have to remake the whole thing. It's not the same, but I hope you understand what I mean.
我什至不确定我必须这样做,我只是读了足够多的书,害怕它在以后的某个阶段不起作用。
InvokeDelegate 实际上是在另一个文件中声明的,但我真的需要一个专门用于此的委托吗?根本没有任何通用代表吗?
我的意思是,例如,有一个 Pen 类,但也有 Pens。选择笔,所以你不必重新制作整个东西。这不一样,但我希望你明白我的意思。
采纳答案by skb
Yes. In .NET 3.5 you can use Funcand Actiondelegates. The Func delegates return a value, while Action delegates return void. Here is what the type names would look like:
是的。在 .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)
I don't know why they stopped at 4 args each, but it has always been enough for me.
我不知道为什么他们每个人都停在 4 args 处,但这对我来说已经足够了。
回答by Fredrik M?rk
Short version:
精简版:
Invoke((MethodInvoker)delegate { Refresh(); });
Then you can also drop the check of InvokeRequired; you can just call it as it is. Works also if you need to pass parameters, so there is no need for other parameter-specific delegates (works just as well with the parameter-less Action delegate as well):
然后你也可以去掉 InvokeRequired 的检查;你可以直接调用它。如果您需要传递参数,也可以使用,因此不需要其他特定于参数的委托(也适用于无参数的 Action 委托):
private void SetControlText(Control ctl, string text)
{
Invoke((MethodInvoker)delegate { ctl.Text = text; });
}
回答by Erik Forbes
There's the Action delegate you could use, like so:
您可以使用 Action 委托,如下所示:
private void RefreshForm()
{
if (InvokeRequired) Invoke(new Action(Refresh));
else Refresh();
}
Or, with lambda syntax:
或者,使用 lambda 语法:
private void RefreshForm()
{
if (InvokeRequired) Invoke((Action)(() => Refresh()));
else Refresh();
}
Finally there's anonymous delegate syntax:
最后是匿名委托语法:
private void RefreshForm()
{
if (InvokeRequired) Invoke((Action)(delegate { Refresh(); }));
else Refresh();
}
回答by mqp
Yes, there are generic delegates. Action<T1, T2...>
is a generic delegate that takes some parameters and returns no value, and Func<T1, T2...R>
is a generic delegate that takes some parameters and returns a value.
是的,有通用代表。 Action<T1, T2...>
是一个接受一些参数并且不返回值Func<T1, T2...R>
的泛型委托,并且是一个接受一些参数并返回一个值的泛型委托。
回答by Juliet
Do I really need an entire delegate dedicated just for this? aren't there any generic delegates at all?
我真的需要一个专门为此专门工作的代表吗?根本没有任何通用代表吗?
Defining your own delegates can really make debugging easier, if only because Intellisense can tell you the names of your parameters. For example, you write a delegate like this:
定义您自己的委托确实可以使调试更容易,因为 Intellisense 可以告诉您参数的名称。例如,您编写这样的委托:
public delegate int UpdateDelegate(int userID, string city, string, state, string zip);
When you use it code, .NET will inform you of the parameter names, delegate name, etc, so there's a lot of context right in the delegate definition if you aren't sure exactly how something is used.
当您使用它的代码时,.NET 会通知您参数名称、委托名称等,因此如果您不确定某些东西的使用方式,那么委托定义中有很多上下文。
However, if you don't mind sacrificing Intellisense, there is already a class of delegates definined in the System namespace which can be used as ad-hoc delegates:
但是,如果您不介意牺牲 Intellisense,那么 System 命名空间中已经定义了一类可用作临时委托的委托:
Func<T>
Func<T, U>
Func<T, U, V>
Func<T, U, V, W>
Action, Action<T>
Action<T, U>
Action<T, U, V>
Action<T, U, V, W>
Only Action
and Action
exist in .NET 2.0, but its easy enough to declare a helper class with the remaining delegates you need for these kind of miscellaneous ad hoc functions.
只有Action
与Action
.NET 2.0中存在,但它足够简单声明一个辅助类,你需要为这些类型的杂特设功能的剩余代表。
回答by Brian ONeil
In this specific case you can (and should) just use MethodInvokerto do this... that is why it exists.
在这种特定情况下,您可以(并且应该)仅使用MethodInvoker来执行此操作……这就是它存在的原因。
if (InvokeRequired)
Invoke(new MethodInvoker(Refresh));
else
Refresh();
If you were doing something else you could, as others have answered use Func<T,...> or Action<T,...> if they fit your use case.
如果您正在做其他事情,您可以,因为其他人已经回答使用 Func<T,...> 或 Action<T,...> 如果它们适合您的用例。