Uso del delegato di azione in C #

Stavo lavorando con i Delegati d’azione in C # nella speranza di saperne di più su di loro e pensando a dove potrebbero essere utili.

Qualcuno ha usato il delegato all’azione e, in caso affermativo, perché? o potresti fornire alcuni esempi in cui potrebbe essere utile?

MSDN dice:

Questo delegato viene utilizzato dal metodo Array.ForEach e dal metodo List.ForEach per eseguire un’azione su ciascun elemento dell’array o dell’elenco.

Tranne che, puoi usarlo come delegato generico che accetta 1-3 parametri senza restituire alcun valore.

Ecco un piccolo esempio che mostra l’utilità del delegato dell’Azione

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

Si noti che il metodo foreach itera la raccolta di nomi ed esegue il metodo di print su ciascun membro della raccolta. Questo è un po ‘un cambiamento di paradigma per noi sviluppatori di C # mentre ci muoviamo verso uno stile di programmazione più funzionale. (Per maggiori informazioni sull’informatica dietro a questo leggi: http://en.wikipedia.org/wiki/Map_(higher-order_function) .

Ora, se stai usando C # 3 puoi sferrarlo un po ‘con un’espressione lambda in questo modo:

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

Beh, una cosa che potresti fare è se hai un interruttore:

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

E con la forza di azione delle azioni è ansible trasformare quell’interruttore in un dizionario:

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

 methodList[SomeEnum](someUser); 

O potresti prendere questo più lontano:

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

….

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

Solo un paio di esempi. Ovviamente l’uso più ovvio sarebbero i metodi di estensione Linq.

È ansible utilizzare le azioni per gestori di eventi brevi:

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

Ho usato il delegato di azioni come questo in un progetto una volta:

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

che tutto ciò che fa è memorizzare un’azione (chiamata di metodo) contro un tipo di controllo in modo da poter cancellare tutti i controlli su un modulo indietro ai valori predefiniti.

Per un esempio di come viene utilizzata l’azione <>.

Console.WriteLine ha una firma che soddisfa l’ 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); } 

Spero che questo ti aiuti

Lo uso quando mi occupo di chiamate Illegal Cross Thread Ad esempio:

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

Devo dare credito a Reed Copsey SO utente 65358 per la soluzione. La mia domanda completa con le risposte è COSÌ Domanda 2587930

L’ho usato come callback in un gestore di eventi. Quando sollevo l’evento, passo un metodo prendendo una stringa come parametro. Ecco come si presenta la raccolta dell’evento:

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

Il metodo:

  public void UpdateMethod(string SpecialCode){ } 

La è la dichiarazione della class dell’evento Arg:

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

In questo modo posso chiamare il metodo passato dal gestore di eventi con un parametro per aggiornare i dati. Lo uso per richiedere alcune informazioni all’utente.

Nei test vengono utilizzate molte funzionalità delegate di Action. Quando abbiamo bisogno di build qualche object predefinito e in seguito è necessario modificarlo. Ho fatto un piccolo esempio. Per build l’object persona predefinita (John Doe) usiamo la funzione BuildPerson() . Successivamente aggiungiamo anche Jane Doe, ma modifichiamo la sua data di nascita, il nome e l’altezza.

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