プログラム言語 ラムダ式
文法
「=>」: GoesTo(ゴーズ・トゥ)
意味 : 左辺の変数を入力値として、右辺の式を実行する
パラメータがない場合
() => 右辺
パラメータが1つの場合
prm => 右辺
パラメータが2つ以上の場合
(prm1, prm2) => 右辺
パラメータの型指定
(int prm) => 右辺
左辺 => 式
左辺 => { 式; 式; 式; }
Delegate
通常文法
private event EventHandler myEvent;
myEvent += new EventHandler(this.myFunction);
private void myFunction(object sender, EventArgs e)
{
Console.WriteLine("通常メソッド");
}
匿名メソッド
myEvent += delegate(object mySender, EventArgs myE) {
Console.WriteLine("匿名メソッド");
};
ラムダ式
myEvent += (mySender, myE) => Console.WriteLine("ラムダ式");
↑ イベントを発生させる
myEvent(sender: this, e: new EventArgs());
delegate void MyDelegator1(string prm);
delegate void MyDelegator2(string prm1, string prm2);
static void Main(string[] args)
{
式形式ラムダ
MyDelegator1 m1 = (n) => Console.WriteLine(n);
m1(@"aaa");
ステートメント形式ラムダ
MyDelegator2 m2 = (n, o) =>
{
for (int i = 0; i < 5;i++ )
{
Console.WriteLine(n);
Console.WriteLine(o);
}
return;
Console.WriteLine(@"aaa");
};
m2(@"aaa", @"bbb");
}
関数型インターフェース/定義済Delegate
戻り値無
delegate void Action(); という宣言が不要
Action act1 = () =>
{
Console.WriteLine(@"aaa");
};
act1();
戻り値:void 引数:n個
delegate void Action(string prm); という宣言が不要
Action<string> act2 = (string prm) =>
{
Console.WriteLine(prm);
};
act2(@"aaa");
Runnable run = () -> { System.out.println("Hello"); };
run.run();
Consumer型 ※引数1つ/戻り値無し
Consumer<String> func = (i) -> { System.out.println(i); };
func.accept("aaa");
戻り値有
delegate string Func(); という宣言が不要
Func<string> fnc1 = () =>
{
return @"bbb";
};
string ret = fnc1();
戻り値:string 引数:n個
delegate string Func(string prm); という宣言が不要
Func<string, string> fnc2 = (string prm) =>
{
return prm + prm;
};
string ret = fnc2(@"bbb");
使用例:何度も呼び出さないサブルーチン
private static string sub1(string a, string b, string c)
{
return a + b + c;
}
static void Main(string[] args)
{
string x = @"A";
string y = @"B";
① 従来の方法(外部にサブルーチンがあり可読性が悪い)
var ret1 = sub1(x, y, @"C");
② 定義済みdelegate & ラムダ式の利用
Func
{
return a + b + c;
};
var ret2 = sub2(x, y, @"C");
③ ↑を短く
Func
var ret3 = sub3(x, y, @"C");
④ x, y を参照しているだけでサブルーチンに渡す必要がないので省略
Func
var ret4 = sub4(@"C");
}
Function型 ※引数1つ/戻り値1つ
Function<Integer, Integer> func = (i) -> { return i*10; };
int ret = func.apply(5);
Supplier型 ※引数無し/戻り値1つ
Supplier<String> func = () -> { return "return"; };
String ret = func.get();
UnaryOperator型 ※引数1つ/戻り値1つで引数、戻り値が同型
UnaryOperator<Integer> func = (i) -> { return i*10; };
int ret = func.apply(5);
戻り値=Bool型、引数有
delegate bool Predicate(int prm); という宣言が不要
Predicate<int> pred = (int i) =>
{
return i > 0;
};
bool ret = pred(5);
Predicate<Integer> func = (i) -> { return i % 3 == 0; };
Boolean ret = func.test(3); // true
関数型インターフェース/delegateを利用した共通処理
{
var obj = ((System.Windows.Forms.Control)(sender));
CommonWork(obj);
}
private void button2_Click(object sender, EventArgs e)
{
var obj = ((System.Windows.Forms.Control)(sender));
CommonWork(obj);
}
private void CommonWork(System.Windows.Forms.Control obj)
{
共通処理
ボタンイベントからの引数に応じて処理を分岐
if (obj == this.button1)
{
個別処理
}
else if (obj == this.button2)
{
個別処理
}
共通処理
}
{
Action myAction = delegate
{
共通関数で実行する個別処理
};
CommonWork(myAction);
}
void button2_Click(object sender, EventArgs e)
{
Action myAction = delegate
{
共通関数で実行する個別処理
};
CommonWork(myAction);
}
void CommonWork(Action myAction)
{
共通処理
引数に渡されたdelegateを実行
処理を分岐する必要無し
myAction();
共通処理
}
Runnable func1 = () -> { System.out.println("AAA");};
Runnable func2 = () -> { System.out.println("BBB");};
// 通常実行
func1.run();
func2.run();
Runnable型のメソッドを渡す
method(func1);
method(func2);
// 引数がRunnable型のメソッド
private void method(Runnable func) {
共通処理
func.run();
共通処理
return;
}
ソート
{
public int myInt { get; set; }
public Item(int prm)
{
this.myInt = prm;
}
}
class MyCompare : System.Collections.IComparer
{
public int Compare(object a, object b)
{
return ((Item)a).myInt – ((Item)b).myInt;
}
}
class Program
{
static void Main(string[] args)
{
Item[] ary = { new Item(prm: 5), new Item(prm: 0), new Item(prm: 10) };
Array.Sort(ary, new MyCompare());
→ 0 5 10
}
}
{
public int myInt { get; set; }
public Item(int prm)
{
this.myInt = prm;
}
}
static void Main(string[] args)
{
Item[] ary = { new Item(prm: 5), new Item(prm: 0), new Item(prm: 10) };
Array.Sort(ary, (x, y) => x.myInt – y.myInt );
→ 0 5 10
}