Risposte:
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 quello, puoi usarlo come delegato generico che accetta 1-3 parametri senza restituire alcun valore.
Ecco un piccolo esempio che mostra l'utilità del delegato 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);
}
}
Si noti che il metodo foreach esegue l'iterazione della raccolta di nomi ed esegue il print
metodo su ciascun membro della raccolta. Questo è un po 'un cambio di paradigma per noi sviluppatori C # mentre ci muoviamo verso uno stile di programmazione più funzionale. (Per maggiori informazioni sull'informatica dietro di essa leggi questo: http://en.wikipedia.org/wiki/Map_(higher-order_function) .
Ora se stai usando C # 3 puoi farlo un po 'su con un'espressione lambda in questo modo:
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();
}
}
Bene, 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 potenza delle azioni puoi trasformare questo interruttore in un dizionario:
Dictionary<SomeEnum, Action<User>> methodList =
new Dictionary<SomeEnum, Action<User>>()
methodList.Add(SomeEnum.One, DoSomething);
methodList.Add(SomeEnum.Two, DoSomethingElse);
...
methodList[SomeEnum](someUser);
Oppure potresti andare oltre:
SomeOtherMethod(Action<User> someMethodToUse, User someUser)
{
someMethodToUse(someUser);
}
....
var neededMethod = methodList[SomeEnum];
SomeOtherMethod(neededMethod, someUser);
Solo un paio di esempi. Naturalmente l'uso più ovvio sarebbero i metodi di estensione Linq.
È possibile utilizzare le azioni per i gestori di eventi brevi:
btnSubmit.Click += (sender, e) => MessageBox.Show("You clicked save!");
Ho usato il delegato d'azione in questo modo in un progetto una volta:
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()}
};
il che non fa altro che archiviare un'azione (chiamata di metodo) contro un tipo di controllo in modo da poter cancellare tutti i controlli di un modulo alle impostazioni predefinite.
Per un esempio di come viene utilizzata l'azione <>.
Console.WriteLine ha una firma che soddisfa 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);
}
Spero che questo ti aiuti
Lo uso quando ho a che fare con chiamate a thread incrociati illegali 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 all'utente Reed Copsey SO 65358 per la soluzione. La mia domanda completa con le risposte è la domanda 2587930
L'ho usato come callback in un gestore eventi. Quando sollevo l'evento, passo un metodo prendendo una stringa un parametro. Ecco come si presenta l'innalzamento dell'evento:
SpecialRequest(this,
new BalieEventArgs
{
Message = "A Message",
Action = UpdateMethod,
Data = someDataObject
});
Il metodo:
public void UpdateMethod(string SpecialCode){ }
È la dichiarazione di classe dell'evento Args:
public class MyEventArgs : EventArgs
{
public string Message;
public object Data;
public Action<String> Action;
}
In questo modo posso chiamare il metodo passato dal gestore eventi con un parametro per aggiornare i dati. Lo uso per richiedere alcune informazioni all'utente.
Usiamo molte funzionalità dei delegati di azione nei test. Quando è necessario creare un oggetto predefinito e successivamente è necessario modificarlo. Ho fatto un piccolo esempio. Per costruire un oggetto persona predefinita (John Doe) usiamo la BuildPerson()
funzione. Più tardi aggiungiamo anche Jane Doe, ma modificiamo 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<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; }
}