3

定期的に操作を起動する必要があるWindowsアプリに取り組んでおり、時間がかかる場合があります。これらの操作をBackgroundWorkerで実行し、操作ごとに簡単なWinFormを作成するパターンになりました。ここで、フォームに必要なパラメーターを渡し、フォームをBackgroundWorkerに接続して、関数呼び出しを行います。フォームに出力が表示されます(プログレスバーの移動、テキストが更新でいっぱいになるなど)。

明らかに、このフォームは非常にクッキーカッターです。フォームコピー間で実際に異なるのは、どのメソッドがどのオブジェクトで呼び出されるかだけです。ですから、私たちがやりたいのは、それを汎用化することです。これにより、フォームを取得し、オブジェクト(静的呼び出しの場合はnull?)、関数名、およびパラメーターの配列を渡して、「実行」することができます。そこから。Reflectionを使用してこれを行うことができました。この場合のリフレクションについて私たちが気に入らないのは、強い型付けがないことです。メソッド呼び出しのスペルミスなどは、コンパイル時ではなく、実行時にキャッチされます。これをよりエレガントで堅牢にする可能性のあるものはありますか?デリゲートやエクスプレッションツリーなどについて話している人の話を聞いたことがあります。しかし、前者が当てはまるかどうかはわかりませんが、後者についてはまだ少し暗闇の中でです。

4

3 に答える 3

6

共通のフォームを作成し、BackgroundWorker で実行する必要があるメソッドを指すデリゲートを渡します。これは賢明な解決策です。

Form コンストラクターに汎用デリゲート (Action が良い考えかもしれません) を引数として取り、Action の署名に一致するラムダ式をコンストラクターに渡すことができます)。次に、foreach アクションで、適切なラムダ式を指定するだけで済みます。

ラムダ式はローカル変数をキャプチャできるため、以前に行ったロジックを呼び出して同じパラメーターを渡すことができることに注意してください。

于 2009-04-06T17:55:36.410 に答える
3

Lambda 関数もチェックアウトすることをお勧めします。ジェネリックを扱うときは特にそれらを使用します。それ以外の場合、デリゲートはおそらく正常に機能します。

于 2009-04-06T18:01:29.360 に答える
2

できることの 1 つは、次のようにいくつかの異なるメソッド (引数のないメソッド用、引数が 1 つのメソッド用など) を作成することです。

public static void DisplayForm(Action action) {
    DisplayFormUsingInvoke(action);
}

public static void DisplayForm<T>(Action<T> action, T param) {
    DisplayFormUsingInvoke(action, param);
}

public static void DisplayForm<T,U>(Action<T,U> action, T param1, U param2) {
    DisplayFormUsingInvoke(action, param1, param2);
}

...

次に、現在のメソッドと同様に、実際に作業を行うプライベート メソッドを作成できますが、クライアント コードには公開されません。

private static void DisplayFormUsingInvoke(Delegate d, params object[] parms) {
    // Edit this code to run it on the background thread, report progress, etc.
    d.DynamicInvoke(parms);
}

次に、クライアント コードは、適切な数と型の引数が提供されるという要件を強制するパブリック メソッドの 1 つを呼び出します。

于 2009-04-06T18:22:16.047 に答える