MSDN заявляет:
Этот делегат используется Массивом. Метод ForEach и Список. Метод ForEach для выполнения действия с каждым элементом массива или списка.
За исключением того, что, можно использовать его в качестве универсального делегата, который берет 1-3 параметра, не возвращая значения.
Вот небольшой пример, который показывает полноценность делегата Действия
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_ (выше-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.
Я использовал делегата действия как это в проекте однажды:
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()}
};
то, которое все это делает, сохранить действие (вызов метода) против типа управления так, чтобы можно было очистить все средства управления на форме назад к там значениям по умолчанию.
Можно использовать действия для коротких обработчиков событий:
btnSubmit.Click += (sender, e) => MessageBox.Show("You clicked save!");
Я использовал его в качестве обратного вызова в обработчике событий. Когда я генерирую событие, я передаю в методе, берущем строку параметр. Это - то, на что похоже повышение события:
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;
}
Этот способ, которым я могу назвать метод, передал от обработчика событий с некоторым параметром для обновления данных. Я использую это, чтобы запросить некоторую информацию от пользователя.
Для примера как Action<> используется.
Консоль. WriteLine имеет подпись тот satisifies 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);
}
Hope это помогает
Я использую его, когда имею дело с незаконными вызовами перекрестных потоков. Например:
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 за решение. Мой полный вопрос с ответами: SO. Вопрос 2587930