匿名メソッドにクロージャーが存在するのはなぜですか? クロージャー変数がコピーされて新しいクラスが生成されるというオーバーヘッドなしに、状態をメソッドに渡すだけではどうですか? これは「すべてをグローバル化する」ことへの逆行ではないでしょうか。
誰かが私を説得してください、私はここで何かが欠けているように感じます...
匿名メソッドにクロージャーが存在するのはなぜですか? クロージャー変数がコピーされて新しいクラスが生成されるというオーバーヘッドなしに、状態をメソッドに渡すだけではどうですか? これは「すべてをグローバル化する」ことへの逆行ではないでしょうか。
誰かが私を説得してください、私はここで何かが欠けているように感じます...
純粋に、便利です...たとえば、次のように定義するときに、必要な状態の量がわかりませんPredicate<T>
。
List<int> data = new List<int> {1,2,3,4,5,6,7,8,9,10};
int min = int.Parse(Console.ReadLine()), max = int.Parse(Console.ReadLine());
List<int> filtered = data.FindAll(i => i >= min && i <= max);
ここでは、状態の2つの追加ビットをPredicate<T>
(min
と)に渡しましたが、それは呼び出し元の詳細であるため、それについて知ることをmax
定義することはできません。List<T>.FindAll(Predicate<T>)
別の方法は、自分でクラスを作成することですが、怠惰な場合でも、それは困難です。
class Finder {
public int min, max;
public bool CheckItem(int i) { return i >= min && i <= max;}
}
...
Finder finder = new Finder();
finder.min = int.Parse(Console.ReadLine());
finder.max = int.Parse(Console.ReadLine());
List<int> filtered = data.FindAll(finder.CheckItem);
あなたのことはわかりませんが、クロージャー付きのバージョンが好きです...特に、複数のコンテキストレベルがある場合にどれほど複雑になるかを考えると。コンパイラに気にしてもらいたい。
特にLINQのようなもので、このような構造を使用する頻度も考慮してください。他の方法で使用する必要はありません...
新しいクラスを作成するオーバーヘッドは、おそらく心配する必要はありません。これは、CLRがバインドされた変数(クロージャーによってキャプチャされた変数)をヒープで使用できるようにするための便利な方法です。それらはまだ閉鎖の範囲内でのみアクセス可能であるため、従来の意味での「グローバル」ではありません。
それらが存在する理由は、主にプログラマーの利便性にあると思います。実際、私に関する限り、それは純粋にそれです。クロージャがC#に存在する前に、クロージャの動作をかなりエミュレートすることはできますが、C#3.0が提供する単純さと構文上の糖衣は得られません。クロージャに関する全体的なポイントは、親スコープの変数は自動的にバインドされるため、関数に渡す必要がないということです。代替案が真のグローバル変数であると考えると、プログラマーは実際に作業するのがはるかに簡単でクリーンになります。
少なくとも1つの考えは、クロージャはjavascriptなどの他の言語に存在するということです。したがって、匿名メソッドに関する人々の以前の経験に沿ったクロージャが含まれている可能性があります。
あなたがこれを書くので:
var divsor = [...]
for(int x = 0; x < 10000000; x++){
source[x] = source[x] / divsor
}
そして簡単にこれに変える
var divsor = [...]
Parallel.For(int x = 0; x < 10000000; x++, ()=> {
source[x] = source[x] / divsor
})
一部のメソッドには、特定の署名が必要です。例えば:
public void set_name_on_click(string name)
{
button.Click += (s,e) => { button.Text = name; };
}
完全な閉鎖はこれを非常にきれいに解決します。匿名メソッドのシグネチャを台無しにしたくはありません。
CLRがそれを処理するため、「状態をメソッドに渡す」最も簡単な方法は、その状態をカプセル化するクラスを自動生成することです。