3

私の知る限り、COMインターフェイスを扱っている場合、単純なキャストは通常QueryInterface​​、オブジェクトが実際に対応するCOMインターフェイスを実装しているかどうかを判断するために使用されるルーチンをトリガーします。

object whatever;
IComInterface casted = (IComInterface) whatever;

したがって、次のコードは、コンパイラと最適化に応じて、内部オブジェクト キャストの実装で をトリガーする可能性があります。QueryInterface

IComInterface comInteface;

// I guess nothing COM-related happens here, but I might be wrong
object whatever = comInteface; 

// This might or might not trigger the 'QueryInterface' call.
IComInterface comInterface2 = (IComInteface) whatever;

Q:

一般的なList<T>インスタンスがあるとします:

List<IComInterface> list = new List<IComInterface>();

QueryInterfaceさて、次のコードがベースのキャストをトリガーしないという強い保証はありますか?

List<IComInterface> list = new List<IComInterface>();
IComInterface comInterface = (...); // Somehow got it.
list.Add(comInteface);
IComInterface retrieved = list[0];
  • ArrayListここで代わりに使用すると、型のないインスタンスからList<T>対応するものを取得する必要があるため、実際にキャストが実行されます。IComInterfaceobject

  • ただし、ジェネリックの場合は、キャストせずにすべてを行う必要があると思いますが、実際にはそれらが表面下でどのように機能するかはわかりません。

  • List<T>どういうわけか型で動作する可能性はありますか(したがって、説明されているシナリオでベースobjectのキャストを呼び出します)?QueryInterface

  • 前の質問に対する答えが「いいえ」の場合、どの可能性についても同じことを保証できないというのは本当IList<T>ですか?

4

2 に答える 2

2

ジェネリック型インスタンス( など) は、ジェネリック型定義( など)List<IComInterface>から作成されたクラスと考えることができます。型は、一部の言語 (特に Java) で行われるように「消去」されるのではなく、ジェネリック型インスタンスと共に保持されるため、ジェネリック型定義で型として宣言されたすべての変数は、ジェネリック型で厳密に型指定されたままになります。実例。List<T>TIComInterfaceT

の場合、コンパイル時にタイプであることがわかっているオブジェクトを挿入する限り、List<IComInterface>へのキャストまたはキャストからのキャストはありません。これは投稿のコードの場合ですが、常に正しいとは限りません。たとえば、動的に型指定されたオブジェクトを挿入すると、コンパイラはキャストを追加します。objectIComInterface

dynamic comInteface = ...
list.Add(comInteface); // There will be an implicit cast here
于 2012-07-12T12:28:16.030 に答える
1

はい、それはかなりまともな保証です。必要でない限り、コンパイラは Opcodes.Castclass IL 命令を発行しません。タイプが一致するため、キャストする必要はありません。

これは一般的には気にする必要はありません。COM インターフェイスの QI 実装は、COM 内部のあらゆる種類の理由で打撃を受けます。GUID の比較には数ナノ秒しかかからず、常に非常に高速です。

于 2012-07-12T12:32:42.580 に答える