我正在与C#中的Action Delegates合作,希望能够更多地了解它们并思考它们可能有用的地方.
有没有人使用过Action Delegate,如果有的话为什么?或者你能举出一些可能有用的例子吗?
这是一个显示Action委托的有用性的小例子
using System; using System.Collections.Generic; class Program { static void Main() { Actionprint = new Action (Program.Print); List names = new List { "andrew", "nicole" }; names.ForEach(print); Console.Read(); } static void Print(String s) { Console.WriteLine(s); } }
请注意,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() { Listnames = new List { "andrew", "nicole" }; names.ForEach(s => Console.WriteLine(s)); Console.Read(); } }
你可以做的一件事就是你有一个开关:
switch(SomeEnum) { case SomeEnum.One: DoThings(someUser); break; case SomeEnum.Two: DoSomethingElse(someUser); break; }
通过动作的强大功能,您可以将该开关转换为字典:
Dictionary> methodList = new Dictionary >() methodList.Add(SomeEnum.One, DoSomething); methodList.Add(SomeEnum.Two, DoSomethingElse);
...
methodList[SomeEnum](someUser);
或者你可以更进一步:
SomeOtherMethod(ActionsomeMethodToUse, User someUser) { someMethodToUse(someUser); }
....
var neededMethod = methodList[SomeEnum]; SomeOtherMethod(neededMethod, someUser);
只是几个例子.当然更明显的用途是Linq扩展方法.
MSDN说:
Array.ForEach方法和List.ForEach方法使用此委托对数组或列表的每个元素执行操作.
除此之外,您可以将它用作通用委托,它接受1-3个参数而不返回任何值.
您可以对短事件处理程序使用操作:
btnSubmit.Click += (sender, e) => MessageBox.Show("You clicked save!");
我曾在项目中使用过这样的动作委托:
private static Dictionary> controldefaults = new Dictionary >() { {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()} };
它所做的只是存储一个控件类型的动作(方法调用),以便您可以清除窗体上的所有控件返回默认值.
有关如何使用Action <>的示例.
Console.WriteLine具有令人满意的签名Action
.
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); }
希望这可以帮助
我在处理非法交叉线程调用时使用它例如:
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(); }));
我必须赞扬Reed Copsey SO用户65358的解决方案.我对答案的完整问题是SO Question 2587930