Antworten:
MSDN sagt:
Dieser Delegat wird von der Array.ForEach-Methode und der List.ForEach-Methode verwendet, um eine Aktion für jedes Element des Arrays oder der Liste auszuführen.
Abgesehen davon können Sie es als generischen Delegaten verwenden, der 1-3 Parameter akzeptiert, ohne einen Wert zurückzugeben.
Hier ist ein kleines Beispiel, das die Nützlichkeit des Aktionsdelegierten zeigt
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);
}
}
Beachten Sie, dass die foreach-Methode die Sammlung von Namen iteriert und die print
Methode für jedes Mitglied der Sammlung ausführt . Dies ist ein Paradigmenwechsel für uns C # -Entwickler, wenn wir uns einem funktionaleren Programmierstil zuwenden. (Weitere Informationen zur dahinter stehenden Informatik finden Sie hier: http://en.wikipedia.org/wiki/Map_(higher-order_function) .
Wenn Sie jetzt C # 3 verwenden, können Sie dies mit einem Lambda-Ausdruck wie folgt etwas verbessern:
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();
}
}
Eine Sache, die Sie tun können, ist, wenn Sie einen Schalter haben:
switch(SomeEnum)
{
case SomeEnum.One:
DoThings(someUser);
break;
case SomeEnum.Two:
DoSomethingElse(someUser);
break;
}
Und mit der Macht der Aktionen können Sie diesen Schalter in ein Wörterbuch verwandeln:
Dictionary<SomeEnum, Action<User>> methodList =
new Dictionary<SomeEnum, Action<User>>()
methodList.Add(SomeEnum.One, DoSomething);
methodList.Add(SomeEnum.Two, DoSomethingElse);
...
methodList[SomeEnum](someUser);
Oder Sie könnten weiter gehen:
SomeOtherMethod(Action<User> someMethodToUse, User someUser)
{
someMethodToUse(someUser);
}
....
var neededMethod = methodList[SomeEnum];
SomeOtherMethod(neededMethod, someUser);
Nur ein paar Beispiele. Die offensichtlichere Verwendung wären natürlich Linq-Erweiterungsmethoden.
Sie können Aktionen für kurze Ereignishandler verwenden:
btnSubmit.Click += (sender, e) => MessageBox.Show("You clicked save!");
Ich habe den Aktionsdelegierten einmal in einem Projekt verwendet:
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()}
};
Sie speichern lediglich eine Aktion (Methodenaufruf) für einen Steuerelementtyp, damit Sie alle Steuerelemente in einem Formular auf die Standardeinstellungen zurücksetzen können.
Ein Beispiel für die Verwendung von Aktion <>.
Console.WriteLine hat eine Signatur, die zufriedenstellend ist 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);
}
Hoffe das hilft
Ich benutze es, wenn ich mit illegalen Cross-Thread-Anrufen zu tun habe. Zum Beispiel:
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();
}));
Ich muss Reed Copsey SO Benutzer 65358 für die Lösung gutschreiben. Meine vollständige Frage mit Antworten ist SO Frage 2587930
Ich habe es als Rückruf in einem Event-Handler verwendet. Wenn ich das Ereignis auslöse, übergebe ich eine Methode, die einen String als Parameter verwendet. So sieht die Auslösung der Veranstaltung aus:
SpecialRequest(this,
new BalieEventArgs
{
Message = "A Message",
Action = UpdateMethod,
Data = someDataObject
});
Die Methode:
public void UpdateMethod(string SpecialCode){ }
Das ist die Klassendeklaration des Ereignisses Args:
public class MyEventArgs : EventArgs
{
public string Message;
public object Data;
public Action<String> Action;
}
Auf diese Weise kann ich die vom Ereignishandler übergebene Methode mit einem Parameter aufrufen, um die Daten zu aktualisieren. Ich benutze dies, um einige Informationen vom Benutzer anzufordern.
In Tests verwenden wir viele Funktionen für Aktionsdelegierte. Wenn wir ein Standardobjekt erstellen und später ändern müssen. Ich habe ein kleines Beispiel gemacht. Um ein Standardobjekt für eine Person (John Doe) zu erstellen, verwenden wir die BuildPerson()
Funktion. Später fügen wir auch Jane Doe hinzu, aber wir ändern ihr Geburtsdatum sowie ihren Namen und ihre Größe.
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; }
}