0

さて、Pythonではこれを行うことができます:

def foo(monkeys):
    def bar(monkey):
        #process and return new monkey
    processed_monkeys = list()
    for monkey in monkeys:
        processed_monkeys += bar(monkey)
    return processed_monkeys

(これは単なるばかげた例です)c#の別のメソッド内でメソッドを宣言するこの機能を見逃すことがあります。しかし、今日、私はこれを達成するために次のアイデアを思いつきました。

List<Monkey> foo(List<Monkey> monkeys)
{
    Func<Monkey, Monkey> bar = delegate(Monkey monkey)
    {
        //process and return new monkey
    }
    List<Monkey> processed_monkeys = new List<Monkey>(monkeys.Count);
    foreach(Monkey monkey in monkeys)
        processed_monkeys.Append(bar(monkey));
    return processed_monkeys;
}

明らかに、回避策は、FuncまたはAction Delegatesが4つのパラメーターに制限されているため、元の機能とまったく同じ機能を提供しませんが、4つを超えるパラメーターが必要になることはめったにありません...

これについてどう思いますか?
これは悪であり、非常に特別な状況を除いてすべて避ける必要がありますか?
これのパフォーマンスはどうですか?関数が呼び出されるたびに新しいbar関数が作成されますか、それともコンパイラーはこれを何らかの方法で最適化しますか?

4

5 に答える 5

5

... Func または Action Delegates は 4 つのパラメータに制限されているため...

.NET 4.0 以降では、これらのデリゲート型は最大 17 個のパラメーターに対して定義されています。任意の数のパラメーターに対して、独自の非常に簡単な定義を行うこともできます。たとえば、以下では、5 つのパラメーターを受け取るデリゲートを定義しています。

public delegate void Action<T1, T2, T3, T4, T5>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5);

これについてどう思いますか。

全然大丈夫です。信じられないかもしれませんが、.NET 開発者は常にこれを行っています。

これは悪であり、非常に特殊な状況以外では避けるべきですか?

いいえ、それはかなり良性です。本当に害はありません。

これの性能はどうですか?関数が呼び出されるたびに新しい bar 関数が作成されますか、それともコンパイラはこれを何らかの形で最適化しますか?

パフォーマンスはかなり良いです。yieldコンパイラは、匿名型およびキーワードを使用するメソッドに対して本格的な CLR 型を定義するのと同様に、匿名メソッドを提供するために実際の本格的な CLR 型を定義します。心配しないで; 匿名メソッドでは、呼び出しごとに動的コンパイルが発生することはありません! 本当に、考えてみれば、それはかなりばかげているでしょう。

これは、私が「最適化」と呼んでいるものでもありません。これは単に、匿名メソッドがコンパイラによって実装される方法です。

于 2010-08-17T12:44:56.907 に答える
2

ラムダ式の構文を使用できるため、コードが少し短くなり、引数が 4 つに制限されることもありません。

var bar = (monkey) => { return new Monkey(); }

私見、それは悪ではありません。デリゲートは確実に 1 回コンパイルされるため、デリゲートと静的メソッドのパフォーマンスの違いはそれほど大きくありません。

もちろん、いつものように、この手法を過度に使用して、読み取り不能/保守不能なコードを作成しないようにする必要があります。

于 2010-08-17T12:46:57.590 に答える
2

コードが読みにくくなれば悪であり、読みやすくなれば善であり、そうでなければ中立です。

于 2010-08-17T12:49:14.453 に答える
0

私は、Scheme を学んだ後、C# でこの「パターン」をかなり多く使用しました。

継続関数として使用できる値をキャプチャするクロージャーを作成すると非常に便利です (特に非同期で使用する場合)。

于 2010-08-17T12:50:03.263 に答える
0

特定のサブ関数がこの関数でのみ使用される場合にのみ、それが良いと考えています。そうでなければ、あなたはそれを繰り返す必要があり、それは私にとって悪になります.

于 2010-08-17T12:51:21.697 に答える