白猫のメモ帳

C#とかJavaとかJavaScriptとかHTMLとか機械学習とか。

Java使いがC#を勉強する その⑩ ラムダ式

こんばんは。

なんだかんだで10回目まで来ました。
環境依存文字の丸で囲んだ数字が⑳まであってよかったね!

今回はラムダ式について見ていきます。

delegateなんてなかったのだ


ラムダ式は要するに匿名関数なのですが、
delegateって何?匿名クラスは?関数オブジェクトは?関数ポインタは?
と、それぞれの言葉の解説をしていくとそれだけでなんだかとっても長くなってしまうのでやめておきます。

Javaのラムダと使い方は大体一緒ですということで。
delegateについてはちゃんと知っておいた方がいいんですかねぇ。

これでばっちり

 

引数 戻り値 Java C# 説明
- - Runnable Action 処理を行う(引数を受け取らない)
- T Supplier<T> Func<T> 値を返す(引数を受け取らない)
T - Consumer<T> Action<T> 処理を行う(値を返さない)
T R Function<T, R> Func<T, R> 引数を受け取り、値を返す
T bool(boolean) Predicate<T> Predicate<T> 条件判定する
T T UnaryOperator<T> Func<T, T> 引数と同一の型を返す(単項演算子
T, T T BinaryOperator<T> Func<T, T, T> 引数と同一の型を返す(二項演算子
T, U R BiFunction<T, U, R> Func<T, U, R> 二引数を受け取り、値を返す
T, U - BiConsumer<T, U> Action<T, U> 二引数を受け取り、値を返さない

はい。よく使うのを一覧にしました。
プリミティブ系は挙げ始めるときりがないので省略です。

基本的にはJavaが関数インタフェースで細分化しているのに対して、
C#ジェネリクスで対応している感じがあります。

が、Predicateだけはこれに当てはまらないようで、
同じラムダでFuncとPredicateに変換できたりします。

// 引数が0か判定するFunc
Func<int, bool> f = a => a == 0;

// 引数が0か判定するPredicate
Predicate<int> p = a => a == 0;

// 型が違うので代入はできない
// f = a;

どういう方針なのでしょう?
あと、「->」と「=>」でちょっと違うのがややこしい。

メソッド参照

 
すでに名前がついているメソッドをdelegate(関数インタフェース)に割り当てることができます。

Javaだとこんな感じに「::」を使います。

// staticメソッド
ToIntFunction<String> methodRef1 = Integer::parseInt;
// インスタンスメソッド
Supplier<String> methodRef2 = ""::toLowerCase;
// コンストラクタ
Supplier<ArrayList> methodRef3 = ArrayList::new;

 
C#では「.」です。
C#にはコンストラクタのメソッド参照はないようです。

// staticメソッド
Func<string, int> methodRef = int.Parse;
// インスタンスメソッド
Func<string> methodRef2 = "".ToLower;

 

LINQは次回

 
ラムダだけやっても使い道が微妙ですね。
JavaでいうところのStreamAPIにあたるLINQは次回。

あ、そういえばJavaではラムダ内から参照できるのはfinalな変数だけですが、
C#ではちゃんとキャプチャできるので、クロージャが作れます。

クロージャ楽しいよね。(混乱するけど)