2016-08-10 6 views
0

デリゲートとラムダ式を理解するのが難しく、stackoverflowの質問のいくつかを読んでこのpostに着いたところ、in this commentが私を完全に失ってしまった。私を混乱させる最初のことは、どこにも定義されていないlistパラメータです(戻り値の型の入力パラメータですが、このコードを理解することは難しいと思います)。しかし、すべてのことが、そのような定義は実際に使用することができます(これは私が苦労して握っている2番目のことです)。デリゲートを返すメソッド

次のような方法を実際にどのように使用できますか?

public Func<IList<T>, T> SelectionMethod<T>() 
{ 
    return list => list.First(); 
} 

public Func<float, float> QuadraticFunctionMaker(float a , float b , float c) 
{ 
    return (x) => { return a * x * x + b * x + c; }; 
} 

答えて

1

パラメータは定義されているだけで、その型が推論されたことになります。引数の定義は、=> - list(タイプがIList<T>であると推測される)およびx(タイプがfloatであると推測される)の前の部分です。第二は

T SomeMethod<T>(IList<T> list) 

float SomeMethod(float x) 

コンパイラはデリゲートの署名がなければならないかを知っているので、それが必要なタイプを推測することができる

最初のデリゲートは、シグネチャに対応します自動的に。あなたが本当に明示的な型を使用する場合は、必要に応じて、あなたはタイプを指定することができます

return (Func<IList<T>, T>)(delegate (IList<T> list) { return list.First(); }); 

あなたは古い学校の明示的な構文を使用してデリゲートを書き出すとしたら、それは次のようになります
(IList<T> list) => list.First() 

あなたが実際にデリゲートを呼び出したいときは、例えば、引数を渡す必要があります:

SelectionMethod<string>()(new List<string>()) 

最初のラムダ式は非常に簡単です。もう1つは、 "creator"関数の引数をさらにクローズします。つまり、デリゲートの本体の「作成者」への引数にアクセスできます。これは純粋に変更不可能なコードでは完全に安全ですが、変更可能な参照型と副作用を扱う場合は難しいかもしれません - セマンティクスを正しく理解してからそれらに夢中になるようにしてください。

関数型プログラミングの経験に応じて、これはすべてコンパイラのトリッキーであることに気付くと役に立ちます。

private class __HiddenAnonymousClass 
{ 
    float a, b, c; 

    public __HiddenAnonymousClass(float a, float b, float c) 
    { 
    this.a = a; this.b = b; this.c = c; 
    } 

    public float __HiddenAnonymousMethod(float x) 
    { 
    return a * x * x + b * x + c; 
    } 
} 

public Func<float, float> QuadraticFunctionMaker(float a , float b , float c) 
{ 
    return new Func<float, float> 
    (new __HiddenAnonymousClass(a, b, c).__HiddenAnonymousMethod); 
} 
: - 私たちは、キャプチャ地元の人々を保持するために「ヘルパーオブジェクト」を作成する必要が

public Func<IList<T>, T> SelectionMethod<T>() 
{ 
    return new Func<IList<T>, T>(__HiddenAnonymousMethod); 
} 

private T __HiddenAnonymousMethod<T>(IList<T> list) 
{ 
    return list.First(); 
} 

第二の例があるため閉鎖のため、より複雑である:二つの方法がこのような何かの同等にコンパイルします

+0

大きな説明。私は、この新しい構文がすべて不明瞭になり、私のコードで構文上のショートカットを避ける傾向があると感じています。コードを読みにくく感じます。 – Stefano

関連する問題