在C#中使用Action委托

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

有没有人使用行动委托,如果是的话,为什么? 或者你能举出一些可能有用的例子吗?

MSDN说:

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

除此之外,你可以使用它作为一个通用的代表,它只需要1-3个参数而不返回任何值。

下面是一个小例子,显示了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); } } 

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

现在,如果您使用的是C#3,那么可以像这样使用lambdaexpression式轻松一点:

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

那么你可以做的一件事是如果你有一个开关:

 switch(SomeEnum) { case SomeEnum.One: DoThings(someUser); break; case SomeEnum.Two: DoSomethingElse(someUser); break; } 

而随着行动的威力,你可以把这个开关转换成字典:

 Dictionary<SomeEnum, Action<User>> methodList = new Dictionary<SomeEnum, Action<User>>() methodList.Add(SomeEnum.One, DoSomething); methodList.Add(SomeEnum.Two, DoSomethingElse); 

 methodList[SomeEnum](someUser); 

或者你可以走这更远的地方:

 SomeOtherMethod(Action<User> someMethodToUse, User someUser) { someMethodToUse(someUser); } 

….

 var neededMethod = methodList[SomeEnum]; SomeOtherMethod(neededMethod, someUser); 

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

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

 btnSubmit.Click += (sender, e) => MessageBox.Show("You clicked save!"); 

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

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

它所做的就是存储一个操作(方法调用)与一个控件types,以便您可以清除窗体上的所有控件回到那里的默认值。

有关如何使用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); } 

希望这可以帮助

我在处理非法跨线程呼叫时使用它例如:

 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的解决scheme。 我的完整问题与答案是SO问题2587930

我用它作为事件处理程序中的callback。 当我提出事件时,我传递一个方法把一个string作为参数。 这就是事件的发展:

 SpecialRequest(this, new BalieEventArgs { Message = "A Message", Action = UpdateMethod, Data = someDataObject }); 

方法:

  public void UpdateMethod(string SpecialCode){ } 

这是事件Args的类声明:

 public class MyEventArgs : EventArgs { public string Message; public object Data; public Action<String> Action; } 

这样我可以调用从事件处理程序传递的一些参数来更新数据。 我用这个来请求用户的一些信息。

我们在testing中使用了很多的Action委托function。 当我们需要build立一些默认的对象,以后需要修改它。 我做了一个小例子。 要构build默认的人(John Doe)对象,我们使用BuildPerson()函数。 后来我们也加了Jane Doe,但是我们修改了她的生日,名字和身高。

 public class Program { public static void Main(string[] args) { var person1 = BuildPerson(); Console.WriteLine(person1.Firstname); Console.WriteLine(person1.Lastname); Console.WriteLine(person1.BirthDate); Console.WriteLine(person1.Height); var person2 = BuildPerson(p => { p.Firstname = "Jane"; p.BirthDate = DateTime.Today; p.Height = 1.76; }); Console.WriteLine(person2.Firstname); Console.WriteLine(person2.Lastname); Console.WriteLine(person2.BirthDate); Console.WriteLine(person2.Height); Console.Read(); } public static Person BuildPerson(Action<Person> overrideAction = null) { var person = new Person() { Firstname = "John", Lastname = "Doe", BirthDate = new DateTime(2012, 2, 2) }; if (overrideAction != null) overrideAction(person); return person; } } public class Person { public string Firstname { get; set; } public string Lastname { get; set; } public DateTime BirthDate { get; set; } public double Height { get; set; } }