C#_ラムダ式
ラムダ式の活用のメリット:ラムダ式の活用のメリット:① 匿名メソッドを2.0の頃の記法より簡単に書ける② 上述の匿名メソッドと同じ記法で式木を作れる
①について
■ 匿名メソッドの記法の簡略化・匿名メソッドの定義から、delegateとか{return}とかの記述を省略できる・型推論機構が働く匿名メソッドをラムダ式を使って書き直す。
例:--------------------------------------------------------------------------------- 匿名メソッド構文--------------------------------------------------------------------------------- delegate(int n) { return n > 0; }--------------------------------------------------------------------------------- 匿名メソッド構文→ラムダ式--------------------------------------------------------------------------------- delegate bool pred(int n);
static void Main(string args) { pred p=(int n) => { return n > 0; }; } --------------------------------------------------------------------------------- ラムダ式:引数の型なし記載方法--------------------------------------------------------------------------------- delegate bool pred(int n);
static void Main(string args) { pred p= n => { return n > 0; }; } --------------------------------------------------------------------------------- ラムダ式:引数の型なし、{},returnなし記載方法--------------------------------------------------------------------------------- delegate bool pred(int n);
static void Main(string args) { pred p=n => n > 0; }---------------------------------------------------------------------------------
②について
■ 式木とは式(数式)を木構造で表したもののこと。
ラムダ式は、Expression型の変数に代入すると、匿名デリゲートではなく、式木としてコンパイルされる。
ラムダ式をあるときには実行コードとして、またあるときはデータとして利用することができる。
デリゲートに代入するか、Expression型に代入するかによってコンパイル結果を変えることで、関数型言語と似たような動作を実現している。
■ 式木の制約:
ラムダ式を式木にできるのは、単文の({ }を使わない)ラムダ式のみ。
四則演算やメソッドコールはできるが、forやwhileなどの制御構文は、式木にできない。
■ 初期化子
C#3.0オブジェクト初期化子で指定できるのはpublicなメンバー変数またはプロパティのみ。(初期化子を書く場所によってはprotechedやinternalも可。初期化子を書いた場所からアクセスできる変数・プロパティのみ)
初期化子のメリット:・クラスのメンバー変数の初期化・式木への代入が可能になる
◇ コレクション初期化
配列と同じように初期化記法を、任意のコレクションクラスに対して行うことができる。また、リスト型のコレクションのみではなく、IDictinary<TKey,TValue>のような辞書クラスに対しても、以下のような記法で初期化できる。(引数2つのAddメソッドが呼ばれる)※コレクションクラス・・System.Collections.IEnumerableインターフェースを実装していて、Addメソッドを持つクラス
◇ インデックス初期化
C#6.0インデクサーを混ぜれるようになった。また、プロパティの代入とインデクサーへの代入を混在させることも可。
例:---------------------------------------------------------------------------------
class Program { static void Main(string args) { // プロパティへの代入とインデクサーへの代入を混在させることができる。 var s = new Sample { Name = "sample", ["X"] = 1, ["Y"] = 2, }; } }
class Sample { // プロパティ_定義 public string Name { get; set; }
// インデクサー_定義 public int this[string key] { get { return 0; } set { } } }
---------------------------------------------------------------------------------
◇ 再帰初期化
再帰的な構造を持ったクラスの初期化もできる。
再帰的な初期化の制限:
メンバーが参照型(class)である必要がある。(値型(struct)だった場合は、コンパイルエラーになる)
(注) 記法での初期化は、インスタンスをnewしてくれたりはしない。コンストラクターもしくはメンバー初期化子での初期化 が必要。