Zastosowanie delegata akcji w C#
Pracowałem z delegatami akcji w C# w nadziei, że dowiem się więcej o nich i zastanowię się, gdzie mogą być przydatne.
Czy ktoś korzystał z delegata akcji, a jeśli tak to dlaczego? a może mógłbyś podać kilka przykładów, gdzie może się to przydać?
9 answers
MSDN says:
Ten delegat jest używany przez / Align = "left" / Metoda ForEach i Lista.Metoda ForEach do wykonania działanie na każdym elemencie tablicy lub lista.
Z tym wyjątkiem, że można go używać jako ogólnego delegata, który pobiera 1-3 parametry bez zwracania żadnej wartości.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-12-16 11:46:16
Oto mały przykład pokazujący przydatność delegata akcji
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);
}
}
Zauważ, że metoda foreach iteruje zbiór nazw i wykonuje metodę print
przeciwko każdemu członkowi zbioru. To trochę zmiana paradygmatu dla nas programistów C#, gdy idziemy w kierunku bardziej funkcjonalnego stylu programowania. (Więcej informacji na temat informatyki za nim przeczytaj to: http://en.wikipedia.org/wiki/Map_ (higher-order_function).
Teraz, jeśli jesteś używając C# 3 możesz to nieco podkręcić wyrażeniem lambda w ten sposób:
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();
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-06-08 21:47:08
Cóż, jedną rzeczą, którą możesz zrobić, jest to, że masz Przełącznik:
switch(SomeEnum)
{
case SomeEnum.One:
DoThings(someUser);
break;
case SomeEnum.Two:
DoSomethingElse(someUser);
break;
}
I z mocą działania możesz zamienić ten przełącznik w Słownik:
Dictionary<SomeEnum, Action<User>> methodList =
new Dictionary<SomeEnum, Action<User>>()
methodList.Add(SomeEnum.One, DoSomething);
methodList.Add(SomeEnum.Two, DoSomethingElse);
...
methodList[SomeEnum](someUser);
Albo możesz wziąć to dalej:
SomeOtherMethod(Action<User> someMethodToUse, User someUser)
{
someMethodToUse(someUser);
}
....
var neededMethod = methodList[SomeEnum];
SomeOtherMethod(neededMethod, someUser);
Tylko kilka przykładów. Oczywiście bardziej oczywistym zastosowaniem byłyby metody rozszerzenia Linq.Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-09-02 17:59:39
Możesz użyć akcji do obsługi krótkich zdarzeń:
btnSubmit.Click += (sender, e) => MessageBox.Show("You clicked save!");
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-12-16 12:07:47
Kiedyś użyłem takiego delegata akcji w projekcie:
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()}
};
Które wszystko, co robi, to przechowuje akcję (wywołanie metody) przeciwko typowi kontrolki, dzięki czemu można wyczyścić wszystkie kontrolki w formularzu z powrotem do domyślnych ustawień.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-12-16 11:53:02
Dla przykładu użycia akcji.
Konsola.WriteLine ma podpis, który odpowiada 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 this helps
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-12-16 12:02:21
Używam go, gdy mam do czynienia z nielegalnymi wywołaniami Cross Thread na przykład:
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();
}));
/ Align = "left" / 65358 Moje pełne pytanie z odpowiedziami to więc pytanie 2587930 Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:02:29
Użyłem go jako wywołania zwrotnego w obsłudze zdarzenia. Kiedy podnoszę Zdarzenie, przekazuję w metodzie biorąc łańcuch parametru. Tak wygląda wydarzenie:
SpecialRequest(this,
new BalieEventArgs
{
Message = "A Message",
Action = UpdateMethod,
Data = someDataObject
});
Metoda:
public void UpdateMethod(string SpecialCode){ }
Jest deklaracją klasy zdarzenia Args:
public class MyEventArgs : EventArgs
{
public string Message;
public object Data;
public Action<String> Action;
}
W ten sposób mogę wywołać metodę przekazaną z obsługi zdarzenia z jakimś parametrem, aby zaktualizować dane. Używam tego, aby zażądać informacji od użytkownika.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-12-16 11:51:08
W testach używamy wielu funkcji delegatów akcji. Kiedy musimy zbudować jakiś domyślny obiekt, a później musimy go zmodyfikować. Zrobiłem mały przykład. Do zbudowania domyślnego obiektu person (John Doe) używamy funkcji BuildPerson()
. Później dodajemy też Jane Doe, ale zmieniamy jej datę urodzenia, imię i wzrost.
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; }
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-08-09 14:50:28