Yanıtlar:
MSDN diyor:
Bu temsilci, dizi veya listenin her öğesinde bir eylem gerçekleştirmek için Array.ForEach yöntemi ve List.ForEach yöntemi tarafından kullanılır.
Bunun dışında, herhangi bir değer döndürmeden 1-3 parametre alan genel bir temsilci olarak kullanabilirsiniz.
İşte Eylem temsilcisinin kullanışlılığını gösteren küçük bir örnek
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 yönteminin ad koleksiyonunu yinelediğine ve yöntemi koleksiyonun print
her üyesine karşı yürüttüğüne dikkat edin . Bu, daha işlevsel bir programlama stiline doğru ilerlerken, biz C # geliştiricileri için biraz paradigma değişikliği. (Arkasındaki bilgisayar bilimi hakkında daha fazla bilgi için şunu okuyun: http://en.wikipedia.org/wiki/Map_(higher-order_function) .
Şimdi, C # 3 kullanıyorsanız, aşağıdaki gibi bir lambda ifadesiyle bunu biraz yukarı kaydırabilirsiniz:
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();
}
}
Yapabileceğiniz şeylerden biri, anahtarınız varsa:
switch(SomeEnum)
{
case SomeEnum.One:
DoThings(someUser);
break;
case SomeEnum.Two:
DoSomethingElse(someUser);
break;
}
Ve eylemlerin gücüyle bu anahtarı bir sözlüğe dönüştürebilirsiniz:
Dictionary<SomeEnum, Action<User>> methodList =
new Dictionary<SomeEnum, Action<User>>()
methodList.Add(SomeEnum.One, DoSomething);
methodList.Add(SomeEnum.Two, DoSomethingElse);
...
methodList[SomeEnum](someUser);
Ya da bu kadar ileri gidebilirsin:
SomeOtherMethod(Action<User> someMethodToUse, User someUser)
{
someMethodToUse(someUser);
}
....
var neededMethod = methodList[SomeEnum];
SomeOtherMethod(neededMethod, someUser);
Sadece birkaç örnek. Elbette daha belirgin kullanım Linq uzatma yöntemleri olacaktır.
Kısa olay işleyicileri için eylemleri kullanabilirsiniz:
btnSubmit.Click += (sender, e) => MessageBox.Show("You clicked save!");
Eylem temsilcisini bir projede bir kez böyle kullandım:
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()}
};
tüm yaptığı bir kontrol türüne karşı bir eylemi (yöntem çağrısı) depolamaktır, böylece bir formdaki tüm kontrolleri oradaki varsayılanlara geri döndürebilirsiniz.
Action <> 'ın nasıl kullanıldığına dair bir örnek için.
Console.WriteLine tatmin edici bir imzaya sahiptir 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);
}
Bu yardımcı olur umarım
Yasadışı Çapraz İş Parçacığı Çağrıları ile uğraşırken kullanıyorum Örneğin:
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();
}));
Çözüm için Reed Copsey SO kullanıcısı 65358'i belirtmeliyim. Cevaplarla ilgili tam sorum SO Soru 2587930
Bunu bir olay işleyicisinde geri arama olarak kullandım. Olayı yükselttiğimde, bir dizge alan bir yöntemi bir parametre olarak iletiyorum. Etkinliğin yükselmesi şuna benziyor:
SpecialRequest(this,
new BalieEventArgs
{
Message = "A Message",
Action = UpdateMethod,
Data = someDataObject
});
Yöntem:
public void UpdateMethod(string SpecialCode){ }
Olay Args'in sınıf bildirimi:
public class MyEventArgs : EventArgs
{
public string Message;
public object Data;
public Action<String> Action;
}
Bu şekilde, verileri güncellemek için olay işleyicisinden geçen yöntemi bir parametre ile çağırabilirim. Bunu kullanıcıdan bazı bilgiler istemek için kullanıyorum.
Testlerde çok sayıda Action delege işlevi kullanıyoruz. Varsayılan bir nesne oluşturmamız gerektiğinde ve daha sonra onu değiştirmemiz gerektiğinde. Küçük bir örnek verdim. Varsayılan kişi (John Doe) nesnesi oluşturmak için BuildPerson()
function kullanıyoruz. Daha sonra Jane Doe'yi de ekliyoruz, ancak doğum tarihini, adını ve boyunu değiştiriyoruz.
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; }
}