Відповіді:
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, ви можете трохи погладшити це за допомогою лямбда-виразу:
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()}
};
що все, що він робить, - це зберігати дію (виклик методу) проти типу керування, щоб ви могли очистити всі елементи керування у формі, повернуті туди за замовчуванням.
Для прикладу того, як використовується 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 за рішення. Моє повне запитання з відповідями - це питання 2587930
Я використовував це як зворотний виклик в обробці подій. Коли я піднімаю подію, я передаю метод, що бере параметр 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;
}
Таким чином я можу викликати метод, переданий від обробника подій, деяким параметром для оновлення даних. Я використовую це, щоб вимагати від користувача деякої інформації.
Ми використовуємо багато функцій делегування дій у тестах. Коли нам потрібно побудувати якийсь об'єкт за замовчуванням, а пізніше потрібно його змінити. Я мало прикладу. Для побудови об'єкта за замовчуванням (John Doe) ми використовуємо BuildPerson()
функцію. Пізніше ми також додаємо Джейн До, але ми змінюємо її дату народження, ім'я та висоту.
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; }
}