私は C# で Action Delegates を使って作業していましたが、それについてもっと学び、どこで役立つかを考えていました。
アクションデリゲートを使用した人はいますか?もしそうなら、それはなぜですか? または、それが役立つ可能性のある例をいくつか挙げていただけますか?
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();
}
}
あなたができることの1つは、スイッチがある場合です:
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 拡張メソッドです。
MSDN は次のように述べています。
このデリゲートは、配列またはリストの各要素に対してアクションを実行するために、Array.ForEach メソッドおよび List.ForEach メソッドによって使用されます。
それ以外は、値を返さずに 1 ~ 3 個のパラメーターを受け取る汎用デリゲートとして使用できます。
短いイベント ハンドラーのアクションを使用できます。
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 の功績を称えなければなりません。回答付きの私の完全な質問はSO Question 2587930 です
イベントハンドラーのコールバックとして使用しました。イベントを発生させるときは、文字列をパラメーターとして受け取るメソッドを渡します。これは、イベントの発生がどのように見えるかです。
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()
関数を使用します。後で Jane Doe も追加しますが、生年月日と名前と身長を変更します。
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; }
}