1

インターフェイスメソッドがあります

  public void Execute(ICommand command);

既知のサブタイプを適切なメソッド実装に渡しICommandHandle(SpecificCommand command)未知のタイプの一般的な処理を行う必要があります。そうするための普遍的な(つまり、巨大なスイッチを必要としない)方法を探しています。

  Handle(command as command.GetType()); // this obviously does not compile

ハンドラーを何らかの方法で登録できることはわかっています。たとえば、ハンドラーをデリゲートとしてディクショナリに格納できますが、これにはまだ処理ロジックを複製する必要があります (特定のHandle(...)メソッド シグネチャで 1 回、デリゲート要求で 1 回)。クラスをリフレクションで調べて (Handle(XXX command)メソッドを探して) ディクショナリを作成すると、パフォーマンスが低下します。

Execute(ICommand command)要約すると、コンパイル時にどのタイプであるかを知らなくても、具体的なタイプを必要とするメソッドを呼び出すために、オブジェクトをダウンキャスト (への呼び出しによってアップキャスト) するにはどうすればよいでしょうか。

4

4 に答える 4

9

さて、「正しい」答えは、Handle() は ICommand のメソッドである必要があるため、 の代わりにHandle(command)と言うでしょうcommand.Handle()

于 2008-12-02T08:46:44.793 に答える
5

キャストはコンパイル時に発行されるため、コンパイル時に型を知る必要があります。オーバーロードもコンパイル時に決定されるため、実際に使用する具象型を知るまでには手遅れです。

デリゲートを使用して実際にロジックを複製しているとは思いません。あるいは、リフレクションを使用すると、Delegate.CreateDelegate を使用してデリゲートを非常に簡単に構築できます。パフォーマンス ヒットは 1 回だけで、その後は非常に高速になります。詳細については、Delegate.CreateDelegate に関する私のブログ エントリを参照してください。

手持ちのメソッドの数と変更頻度に基づいて、手作りの辞書またはリフレクションを使用して構築された辞書を使用することを決定すると思います。KeyedByTypeCollectionがディクショナリに役立つことがわかるでしょう。

于 2008-12-02T09:04:13.167 に答える
2

あなたはできません、そしてなぜあなたはしたいのですか?

それが、ポリモーフィズムがある理由です。特定の型に固有のカスタム動作が必要な場合は、その動作が型自体に存在し、基本クラスの型で宣言された関数を介して呼び出される必要があります。

于 2008-12-02T08:45:14.750 に答える
1

Double Dispatch( http://en.wikipedia.org/wiki/Double_dispatch )を使用して機能する方法を試しましたが、ICommandを実装するクラスとExecute(を実装するクラスの数が多いようです。 )は実行時に(または、少なくともコンパイルと実行の間で、本質的に同じことです)変化する可能性があるため、私が見ることができる唯一の解決策は、JonSkeetが提案したように辞書を使用します。

于 2008-12-02T15:29:12.267 に答える