13

私はもっ​​とよく理解したいと思っている非常に奇妙な何かを発見しました。

var all = new List<int[]>{
                new int[]{1,2,3},
                new int[]{4,5,6},
                new int[]{7,8,9}
              };

all.ForEach(n => n.ForEach(i => Console.WriteLine(i)));

これは次のように書き直すことができます。

...
all.ForEach(n => n.ForEach(Console.WriteLine));

ラムダ式パラメーター(i =>)を省略しても、現在のアイテムをconsole.WriteLineに渡すにはどうすればよいですか?

洞察をありがとう。-キース

4

2 に答える 2

33

List<T>.ForEachを探していAction<T>ます。あなたが書くとき

n.ForEach(Console.WriteLine);

ここにあるのはConsole.WriteLine、の役割を果たすメソッドグループのメンバーの1つですAction<T>Console.WriteLineコンパイラは、のインスタンスを食べるのに最適なオーバーロードを探しますint。実際には、オーバーロードを使用しConsole.WriteLine(int)ます。次に、このオーバーロードを使用して、の役割を果たしAction<int>ます。

これがどのように行われるかの詳細については、仕様の§6.6(メソッドグループ変換)を参照してください。

しかし、あなたが書くとき

n.ForEach(i => Console.WriteLine(i));

私たちは実際には非常に異なっていますAction<int>最初のケースでは、Action<int>でしたConsole.WriteLine(int)。ここでは、Action<int>あなたが書いたのと同じです

public static void DoSomething(int i) {
    Console.WriteLine(i);
}

その後

n.ForEach(DoSomething);

(もちろん、コンパイラーは、上記と同じメソッドグループプロセスを実行して、の意味を理解する必要がありDoSomethingます)。

重要なのは、最初のケースでAction<int> はです Console.WriteLine(int)。ただし、2番目のケースでAction<int>は、はそれ自体がを呼び出す中間者(ラムダ式)ですConsole.WriteLine(int)

于 2010-02-09T16:07:52.407 に答える
2

実際に何が起こっているかを考えれば、これはそれほど混乱しません。

メソッドをデリゲート引数に渡しています。ほとんどの場合、イベントのコンテキストでデリゲートを考えますが、メソッドのパラメーターにすることもできます。メソッドが引数なしでイベントに追加された場合、それは奇妙に見えません。このコンテキストで実行された場合、見た目は異常です。

ラムダの前は、これを常に行う必要があり、LINQのようなライブラリの使用を検討することは決してないほどの苦痛でした。Lambdasを使用すると、これを行うのは簡単ですが、いつでも古い方法で行うことができます。

于 2011-01-30T05:43:28.047 に答える