21

System.Object を拡張することは通常悪い習慣であると読んだことがありますが、これには同意します。

私は興味がありますが、以下が有用な拡張メソッドと見なされるか、それともまだ悪い習慣ですか?

System.Object の拡張に似ていますが、厳密には異なります。

    public static R InvokeFunc<T, R>(this T input, Func<T, R> func)
    {
        return func.Invoke(input);
    }

これにより、関数がオブジェクトに属しているかどうかに関係なく、オブジェクトをパラメーターとして取り、R を返す任意の関数を任意のオブジェクトで呼び出すことができます。これにより、興味深い「制御の反転」が容易になると思いますが、全体的にはわかりません。

考え?

4

2 に答える 2

2

さて、ここには本当に 2 つのポイントがあります。

this T1)すべての型に適用されるように、拡張メソッドを作成することをお勧めしますか?

2) 説明されている特定の拡張方法が有用かどうか。

最初の質問の答えは時々ありますが、文脈によって異なります。linq が適切な名前空間を確実に選択するように、拡張メソッドをすべてのクラスに適用することができます。System 名前空間内にこのタイプの拡張メソッドを作成するのは悪い考えだと思いますが、より対象を絞ったものであれば、おそらく役立つでしょう。

呼び出しが即時であるため、2番目の場合、構文の選択は次のとおりです

    int res = other.InvokeFunc<Other, int>(Callback);

    var res2 = (new Func<Other, int>(Callback))(other);

    var res3 = Callback(other);

それを見ると、インスタンスを渡すメソッドへの単純な呼び出しはより自然で典型的ですが、拡張メソッドがより複雑になると、コンテキストに依存するという最初のポイントに戻ります (カプセル化に役立つ可能性があります)。 .

于 2011-04-15T00:50:21.460 に答える
1

これが行うことは、メソッドをパラメーターとして参照できるようにすることだけです。これは、実際には、デリゲートが C# で既に許可しているものです。

あなたの場合、タイプのデリゲートよりも(IoCの場合)便利だとは思いませんFunc<T,R>。それを呼び出す別の方法です。

アップデート

コメントで述べたように、この方法はデリゲートをより効率的に作成するのに役立つだけだと思います。ただし、いずれにしても、作成したデリゲートはすぐに呼び出すため、それ以上使用する必要はありません。したがって、このような拡張メソッドは私にとってより理にかなっています:

public static Func<R> InvokeFunc<T, R>(this T input, Func<T, R> func)
{
    return () => func(input);
}
于 2011-04-14T23:03:42.347 に答える