2

サブクラスのセット(productorder、specialorder、partsorderなど)を持つ基本クラス(注文)があります。

これらのサブクラスの一部のみが、単一のメソッド宣言 (オブジェクト getcustdetails()) を持つ特定のインターフェイス (ITrackingCustomer) を実装します。

私のソリューションの一部として、すべての注文は中央の場所で処理されます。つまり、すべてのクラッド メソッドは中央のレイヤーを通過します。この中央レイヤー内で、次のことを行います。

注文のタイプが ITrackingCustomer の場合

次に、メソッド getcustdetails() を呼び出します

次のコードを使用してこれを機能させています。

if (typeof(ITrackingCustomer).IsAssignableFrom(Order.GetType())) 
{ 
     MethodInfo theMethod = Order.GetType().GetMethod("getcustdetails"); 
     object y = theMethod.Invoke(Order, null); 
} 

isassignablefrom を使用した最初の部分には満足していますが、2 番目の部分 (つまり、invoke を使用したリフレクション) では、パフォーマンスをあまり重視しない方法を使用したいと考えています。

私の質問は:

呼び出しコマンドを使用するとコストがかかることを読んだので、これを行うより効率的な方法はありますか。

4

4 に答える 4

6
ITrackingCustomer ord = Order as ITrackingCustomer;
if (ord != null)
{
    object y = ord.getcustdetails();
}
于 2010-01-28T14:58:27.693 に答える
1

他の人が述べたように、isandas演算子を使用して、オブジェクトが特定のタイプであるかどうかを判別できます。ただし、通常、このタイプの問題を解決するには、ポリモーフィズムの方が適しています。

可能であれば、getcustdetails()メソッドをに配置できますOrder。適切virtualなデフォルトの実装がある場合(つまり、詳細を返さない、またはnull)、またはすべてのタイプがそれを実装する必要abstractがあることが理にかなっている場合に作成します。OrderあなたはITrackingCustomerインターフェースを持っているので、abstractメソッドはうまく機能しないのではないかと思います。ただし、を実装するOrderタイプITrackingCustomerの場合は、それに応じて実装できますgetcustdetails()

現時点では、を廃止できるように思われますがITrackingCustomer、このインターフェイスの使用方法について詳しく知らなければ、はっきりとは言えません。

Order.getcustdetails()これが完了すると、呼び出しは常に正しい具象実装にディスパッチされるため、型チェックを実行する必要はありません。

于 2010-01-28T15:12:02.340 に答える
1

できるよ:

if(Order is ITrackingCustomer) {
    ((ITrackingCustomer)Order).getcustdetails();
}
于 2010-01-28T14:58:08.290 に答える
0

インターフェイスでメンバーを呼び出すのではなく、名前で呼び出しを実行しようとしていて、同じメソッドを何千回も呼び出せるようにしたい場合は、キャスト以外の方法を使用します (キャストを使用しないため、実行できないと思います)。タイプがわからない場合) またはリフレクションは、呼び出しを JIT コンパイルすることです。

Rick Strahl は、メソッドを呼び出すさまざまな方法のパフォーマンス コストに関するすばらしいブログ記事を持っています。コメントは、デリゲートを非仮想メソッドに引き出す方法を示すこの記事につながります。

最後に、アダプター クラスをオンザフライでビルドする方法に関するブログ記事を書きました。これでできることは、抽象クラスを満たす直接呼び出し可能なオブジェクトを作成することです。

public abstract class CustomerDetailsGetter {
    public abstract object getcustdetails();
}

// ...

AdapterCompiler compiler = new AdapterCompiler();
AdapterFactory<CusomterDetailsGetter> factory = compiler.DefineAdapter<CustomerDetailsGetter>(Order.GetType());

// now, my code assumes you want to construct an object from whole cloth
// but the code could be changed to invoke the default constructor and set the
// adapted object.

CustomerDetailsGetter getter = factory.Construct(null)

object info = getter.getcustdetails();

ここで、明確にする必要があります。これを行う理由は 2 つだけです。

  1. コンパイル時にターゲット引数がわかっているが、ターゲット アセンブリがあることがわからない場合に、名前による呼び出しのセマンティクスを使用できるようにする必要があり、コードをクリーンにしたい場合。この例として、特定のオブジェクトを作成して使用する必要があることを認識しているが、アセンブリが実行時まで使用できるかどうかを認識しておらず、参照を持つことが禁止されているコードがあります。

  2. オブジェクトメソッドを反射的に呼び出したいが、これを高速、高速、高速で実行したい場合、それらを何千回または何百万回も呼び出すことになります。

それが「1 回呼び出す」ものである場合は、ヘルパー メソッドを記述して、必要なことを行う方がはるかに優れています。

于 2010-01-28T15:30:52.490 に答える