Usos del delegado de Acción en C #

Estaba trabajando con los Delegados de Acción en C # con la esperanza de aprender más sobre ellos y pensar dónde podrían ser útiles.

Alguien ha usado el Delegado de Acción, y si es así, ¿por qué? o podría dar algunos ejemplos donde podría ser útil?

MSDN dice:

Este delegado es utilizado por el método Array.ForEach y el método List.ForEach para realizar una acción en cada elemento de la matriz o lista.

Excepto que puede usarlo como un delegado genérico que toma 1-3 parámetros sin devolver ningún valor.

Aquí hay un pequeño ejemplo que muestra la utilidad del delegado de Acción

using System; using System.Collections.Generic; class Program { static void Main() { Action print = new Action(Program.Print); List names = new List { "andrew", "nicole" }; names.ForEach(print); Console.Read(); } static void Print(String s) { Console.WriteLine(s); } } 

Observe que el método foreach itera la colección de nombres y ejecuta el método de print contra cada miembro de la colección. Este es un cambio de paradigma para los desarrolladores de C # de nosotros a medida que avanzamos hacia un estilo de progtwigción más funcional. (Para obtener más información sobre la ciencia de la computación que hay detrás, lea esto: http://en.wikipedia.org/wiki/Map_(higher-order_function) .

Ahora, si estás usando C # 3, puedes deslizar esto un poco con una expresión lambda así:

 using System; using System.Collections.Generic; class Program { static void Main() { List names = new List { "andrew", "nicole" }; names.ForEach(s => Console.WriteLine(s)); Console.Read(); } } 

Bueno, una cosa que podrías hacer es si tienes un interruptor:

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

Y con el poder de las acciones, puede convertir ese cambio en un diccionario:

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

 methodList[SomeEnum](someUser); 

O podrías llevar esto más lejos:

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

….

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

Solo un par de ejemplos. Por supuesto, el uso más obvio serían los métodos de extensión Linq.

Puede usar acciones para manejadores de eventos cortos:

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

Utilicé el delegado de acción de esta manera en un proyecto una vez:

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

lo único que hace es almacenar una acción (llamada de método) contra un tipo de control para que pueda borrar todos los controles en un formulario de nuevo a sus valores predeterminados.

Para ver un ejemplo de cómo se usa Action <>.

Console.WriteLine tiene una firma que satisface 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); } 

Espero que esto ayude

Lo uso cuando estoy tratando con llamadas ilegales cruzadas, por ejemplo:

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

Debo dar crédito al usuario de Reed Copsey SO 65358 por la solución. Mi pregunta completa con respuestas es SO Pregunta 2587930

Lo usé como una callback en un controlador de eventos. Cuando planteo el evento, paso un método tomando una cadena de un parámetro. Así es como se ve el evento:

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

El método:

  public void UpdateMethod(string SpecialCode){ } 

La es la statement de clase del evento Args:

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

De esta forma puedo llamar al método pasado desde el controlador de eventos con algún parámetro para actualizar los datos. Lo uso para solicitar información del usuario.

Usamos mucha funcionalidad de delegado de Acción en las pruebas. Cuando necesitamos construir algún objeto predeterminado y luego necesitamos modificarlo. Hice un pequeño ejemplo. Para construir un objeto de persona predeterminado (John Doe) utilizamos la función BuildPerson() . Más tarde agregamos a Jane Doe también, pero modificamos su fecha de nacimiento, nombre y altura.

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