C#小ネタ集
前提
C#ではラムダをvarで受けることができません。
例えば次のコードはコンパイルエラーになります
// ラムダ式 を暗黙的に型指定された変数に割り当てることはできません
var f = i => true;
これは、ラムダが左辺の型定義によって、柔軟に解釈される影響だと推測されます。
Func<int, bool> f1 = i => true;
Expression<Func<int, bool>> f2 = i => true;
Predicate<int> f3 = i => true;
そのため、コード上に型を書くことができない匿名型を返すラムダは一見記述不可能のようにみえます。
Func<int, /* ここに型が書けない */> f = i => new { Age = i };
Genericsメソッドによる型推論
varによる型推論はできないものの、Genericsメソッド引数としてラムダを渡すことにより、Func<>の型引数を推論することは可能です。
これを利用することにより、以下のように、匿名型を返すラムダを定義することができます。
static void Main(string[] args)
{
// C#7ならローカル関数でもOK
Func<int, T> ToLambda<T>(Func<int, T> f1) => f1;
var f = ToLambda(i => new { Age = i });
var a = f(10); // 匿名型を返す
}
static Func<int, T> ToLambda<T>(Func<int, T> f1) => f1;
余談
VB.NETでは型推論でいい感じに解決してくれるので、小細工不要だったりします。
' 全てコンパイル可能
Dim f = Function( i as Integer) True
Dim f1 As Func(Of Integer, Boolean) = Function( i as Integer) True
Dim f2 As Expression(Of Func(Of Integer, Boolean)) = Function( i as Integer) True