简体   繁体   English

C#中的匿名代表

[英]anonymous delegates in C#

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 really need an entire delegate dedicated just for this? InvokeDelegate实际上是在另一个文件中声明的,但是我真的需要一个专门为此专用的整个委托吗? aren't there any generic delegates at all? 根本没有通用委托吗?
I mean, for example, there's a Pen class, but there's also Pens. 我的意思是,例如,有一个Pen课程,但也有Pens。 pen-of-choice so you don't have to remake the whole thing. 选择,因此您不必重新制作整个内容。 It's not the same, but I hope you understand what I mean. 是不一样的,但我希望你能理解我的意思。

Yes. 是。 In .NET 3.5 you can use Func and Action delegates. 在.NET 3.5中,您可以使用FuncAction委托。 The Func delegates return a value, while Action delegates return void. Func委托返回一个值,而Action委托返回void。 Here is what the type names would look like: 这是类型名称的样子:

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个参数上,但是对我来说一直就足够了。

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();
}

In this specific case you can (and should) just use MethodInvoker to 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,...>(如果它们适合您的用例)。

Short version: 简洁版本:

Invoke((MethodInvoker)delegate { Refresh(); });

Then you can also drop the check of InvokeRequired; 然后,您还可以取消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): 如果您需要传递参数,则也可以使用,因此不需要其他特定于参数的委托(与无参数的Action委托也一样):

private void SetControlText(Control ctl, string text)
{
    Invoke((MethodInvoker)delegate { ctl.Text = text; });
}

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. 仅仅因为Intellisense可以告诉您参数的名称,定义您自己的委托确实可以使调试更加容易。 For example, you write a delegate like this: 例如,您编写这样的委托:

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. .NET 2.0中仅存在ActionAction ,但是它很容易声明带有此类杂项临时功能所需的其余委托的帮助器类。

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>是接受一些参数并且返回值的泛型委托。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM