在C#中使用Action委托

Bis*_*ath 132 c# lambda delegates action

我正在与C#中的Action Delegates合作,希望能够更多地了解它们并思考它们可能有用的地方.

有没有人使用过Action Delegate,如果有的话为什么?或者你能举出一些可能有用的例子吗?

And*_*are 114

这是一个显示Action委托的有用性的小例子

using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        Action<String> print = new Action<String>(Program.Print);

        List<String> names = new List<String> { "andrew", "nicole" };

        names.ForEach(print);

        Console.Read();
    }

    static void Print(String s)
    {
        Console.WriteLine(s);
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,foreach方法迭代名称集合并print针对集合的每个成员执行方法.这对我们C#开发人员来说是一种范式转换,因为我们正朝着更具功能性的编程风格迈进.(有关其背后的计算机科学的更多信息,请阅读:http://en.wikipedia.org/wiki/Map_(higher-order_function).

现在,如果你正在使用C#3,你可以使用lambda表达式来修改它,如下所示:

using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        List<String> names = new List<String> { "andrew", "nicole" };

        names.ForEach(s => Console.WriteLine(s));

        Console.Read();
    }
}
Run Code Online (Sandbox Code Playgroud)


Pro*_*ool 67

你可以做的一件事就是你有一个开关:

switch(SomeEnum)
{
  case SomeEnum.One:
      DoThings(someUser);
      break;
  case SomeEnum.Two:
      DoSomethingElse(someUser);
      break;
}
Run Code Online (Sandbox Code Playgroud)

通过动作的强大功能,您可以将该开关转换为字典:

Dictionary<SomeEnum, Action<User>> methodList = 
    new Dictionary<SomeEnum, Action<User>>()

methodList.Add(SomeEnum.One, DoSomething);
methodList.Add(SomeEnum.Two, DoSomethingElse); 
Run Code Online (Sandbox Code Playgroud)

...

methodList[SomeEnum](someUser);
Run Code Online (Sandbox Code Playgroud)

或者你可以更进一步:

SomeOtherMethod(Action<User> someMethodToUse, User someUser)
{
    someMethodToUse(someUser);
}  
Run Code Online (Sandbox Code Playgroud)

....

var neededMethod = methodList[SomeEnum];
SomeOtherMethod(neededMethod, someUser);
Run Code Online (Sandbox Code Playgroud)

只是几个例子.当然更明显的用途是Linq扩展方法.

  • 很好 - 这是一种重构模式"用多态替换条件".http://www.refactoring.com/catalog/replaceConditionalWithPolymorphism.html (3认同)

aru*_*rul 25

MSDN说:

Array.ForEach方法和List.ForEach方法使用此委托对数组或列表的每个元素执行操作.

除此之外,您可以将它用作通用委托,它接受1-3个参数而不返回任何值.


Aar*_*ell 16

您可以对短事件处理程序使用操作:

btnSubmit.Click += (sender, e) => MessageBox.Show("You clicked save!");
Run Code Online (Sandbox Code Playgroud)


Nat*_*n W 15

我曾在项目中使用过这样的动作委托:

private static Dictionary<Type, Action<Control>> controldefaults = new Dictionary<Type, Action<Control>>() { 
            {typeof(TextBox), c => ((TextBox)c).Clear()},
            {typeof(CheckBox), c => ((CheckBox)c).Checked = false},
            {typeof(ListBox), c => ((ListBox)c).Items.Clear()},
            {typeof(RadioButton), c => ((RadioButton)c).Checked = false},
            {typeof(GroupBox), c => ((GroupBox)c).Controls.ClearControls()},
            {typeof(Panel), c => ((Panel)c).Controls.ClearControls()}
    };
Run Code Online (Sandbox Code Playgroud)

它所做的只是存储一个控件​​类型的动作(方法调用),以便您可以清除窗体上的所有控件返回默认值.


Bin*_*ier 13

有关如何使用Action <>的示例.

Console.WriteLine具有令人满意的签名Action<string>.

    static void Main(string[] args)
    {
        string[] words = "This is as easy as it looks".Split(' ');

        // Passing WriteLine as the action
        Array.ForEach(words, Console.WriteLine);         
    }
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助


Ron*_*fca 11

我在处理非法交叉线程调用时使用它例如:

DataRow dr = GetRow();
this.Invoke(new Action(() => {
   txtFname.Text = dr["Fname"].ToString();
   txtLname.Text = dr["Lname"].ToString(); 
   txtMI.Text = dr["MI"].ToString();
   txtSSN.Text = dr["SSN"].ToString();
   txtSSN.ButtonsRight["OpenDialog"].Visible = true;
   txtSSN.ButtonsRight["ListSSN"].Visible = true;
   txtSSN.Focus();
}));
Run Code Online (Sandbox Code Playgroud)

我必须赞扬Reed Copsey SO用户65358的解决方案.我对答案的完整问题是SO Question 2587930