サーチ…


備考

閉鎖

ラムダ式は暗黙的に使用される変数を取り込み、クロージャを作成します 。クロージャは、いくつかの状態コンテキストと共に関数です。コンパイラは、ラムダ式がその周囲の文脈からの値を '囲む(enclose)'たびにクロージャを生成する。

例:以下の場合

Func<object, bool> safeApplyFiltererPredicate = o => (o != null) && filterer.Predicate(i);

safeApplyFilterPredicateは、 filtererの現在の値へのプライベート参照を持ち、 Invokeメソッドが次のように動作する、新しく作成されたオブジェクトを参照します

o => (o != null) && filterer.Predicate(i);

safeApplyFilterPredicateの値の参照が維持されているsafeApplyFilterPredicatesafeApplyFilterPredicateが現在参照しているオブジェクトへの参照が存在するため、これはfiltererです。これはガベージコレクションに影響し、現在filtererいるオブジェクトがfilterer場合に予期しない動作が発生する可能性があります。

一方、クロージャを使用して、他のオブジェクトへの参照を含むビヘイビアをカプセル化するエフェクトを考察することができます。

例えば

var logger = new Logger();
Func<int, int> Add1AndLog = i => {
    logger.Log("adding 1 to " + i);
    return (i + 1);
};

クローズを使用して状態マシンをモデル化することもできます。

Func<int, int> MyAddingMachine() {
    var i = 0;
    return x => i += x;
};

基本的なラムダ式

Func<int, int> add1 = i => i + 1;

Func<int, int, int> add = (i, j) => i + j;

// Behaviourally equivalent to:

int Add1(int i)
{
    return i + 1;
}

int Add(int i, int j)
{
    return i + j;
}

...

Console.WriteLine(add1(42)); //43
Console.WriteLine(Add1(42)); //43
Console.WriteLine(add(100, 250)); //350
Console.WriteLine(Add(100, 250)); //350

LINQを使った基本ラムダ式

// assume source is {0, 1, 2, ..., 10}

var evens = source.Where(n => n%2 == 0);
// evens = {0, 2, 4, ... 10}

var strings = source.Select(n => n.ToString());
// strings = {"0", "1", ..., "10"}

ラムダ構文を使用してクロージャを作成する

クロージャの議論については、備考を参照してください。インターフェイスがあるとします。

public interface IMachine<TState, TInput>
{
    TState State { get; }
    public void Input(TInput input);
}

以下のように実行される。

IMachine<int, int> machine = ...;
Func<int, int> machineClosure = i => {
    machine.Input(i);
    return machine.State;
};

machineClosureから関数を参照するintにするint舞台裏使用し、 IMachineインスタンスmachine計算を行うためにを意味します。参照machineが有効範囲外になっても、 machineClosureオブジェクトが維持されている限り、元のIMachineインスタンスはコンパイラによって自動的に定義される 'クロージャ'の一部として保持されます。

警告:これは、同じ関数呼び出しが異なる時刻に異なる値を返すことを意味する可能性があります(たとえば、マシンが入力の合計を保持している場合など)。多くの場合、これは予期しないものであり、機能的なスタイルのコードでは避けるべきです。偶発的で予期しないクロージャーがバグの原因となります。

文ブロックボディを含むラムダ構文

Func<int, string> doubleThenAddElevenThenQuote = i => {
    var doubled = 2 * i;
    var addedEleven = 11 + doubled;
    return $"'{addedEleven}'";
};

System.Linq.Expressionsによるラムダ式

Expression<Func<int, bool>> checkEvenExpression = i => i%2 == 0;
// lambda expression is automatically converted to an Expression<Func<int, bool>>


Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow