3

コンストラクターでさまざまな数の Func デリゲートを渡す必要があるクラスがあります。これらのデリゲートはそれぞれ、戻り値の型が異なり、さまざまな数のパラメーター (double 型) を持つ異なる関数を指します。これらの各関数は、それに応じて呼び出されます。

List<object>質問 1. 現在、このクラスを使用している方の作業を簡単にするために、ユーザーが Func デリゲートの a を渡せるようにすることを考えています。List<object>これは可能ですか?もしそうなら、が渡されるメソッド(つまり、コンストラクター)の各 Func に必要な戻り値の型とパラメーターの数を判断できますか?

質問2.上記が実現できない場合、戻り値の型/パラメーターの数のさまざまな組み合わせでコンストラクターをオーバーロードし、それに応じて各Funcをルーティングする必要がありますか-_- ...そうでない場合、誰かが私を正しい方向に向けることができます私はこれに間違った方法でアプローチしているように感じます...

注-Pythonのバックグラウンドから来て、私は次のようなことをします(私はc#の経験がありません):

import inspect
def test(x): return x
inspect.getargspec(test)

returns: ArgSpec(args=['x'], varargs=None, keywords=None, defaults=None)

どうもありがとう

4

1 に答える 1

7

質問 1. 現在、このクラスを使用している方に簡単にするために、ユーザーが Func デリゲートのリストを渡せるようにすることを考えています。これは可能ですか?もしそうなら、リストが渡されるメソッド(つまり、コンストラクター)の各 Func に必要な戻り値の型とパラメーターの数を判断できますか?

あまり。List<Delegate>a (または要素タイプが の他のコレクション) を許可することはできますが、次の 2 つの理由から、固有のDelegateものは許可しません。Func

  • Func事実上、さまざまな数のジェネリック型パラメーターを持つ型のファミリです。これらの型は、CLR に関する限り、完全に分離されています。Func<TResult>とは ととFunc<T, TResult>同じくらい異なります。Action<T>EventHandler

  • デリゲートの同じジェネリック型のいくつかの値のみを扱っていたとしても、それらが異なる型引数を持つ可能性があるという事実は、それらが CLR に対して異なる型であることを意味します。List<Func<>>「潜在的に異なる型引数を持つ関数のリスト」とは言えません。繰り返しますが、CLR はそれらを個別の型として扱いますが、今回は少なくとも 1 つの共通のジェネリック型定義があります。

質問 2. 上記が実現不可能な場合、戻り値の型/パラメーターの数のさまざまな組み合わせごとにコンストラクターをオーバーロードし、それに応じて各 Func をルーティングする必要がありますか?

さて、いくつかのオプションがあります:

  • すべてのパラメーターをオプションにして、それぞれにデフォルト値の をnull指定し、コンストラクターを呼び出すときに名前付き引数を使用します。

     var foo = new Foo(clickHandler: () => ...,
                       keyHandler: key => ...);
    
  • さまざまな関数をプロパティとして設定できるように、ビルダーを作成します。これは、オブジェクト初期化構文で非常にうまく機能します。

     var foo = new Foo.Builder {
                   ClickHandler = () => ...,
                   KeyHandler = () => ...
               }.Build();
    

もちろん、後者のソリューションはどちらも、特定の名前付きの目的を実際に持っているかどうかに依存します。

達成しようとしていることをより明確にすることができれば役立ちます-dtbが言うように、ここではポリモーフィズムより適している可能性があります。仮想メソッドの no-op 実装を使用して抽象クラスを作成し、実装でオーバーライドするものを選択できます。

于 2013-03-23T21:14:47.357 に答える