As far as I know, if we're dealing with COM
interfaces, any simple cast will usually trigger the QueryInterface
routine, which is used to determine if the object actually implements the corresponding COM
interface.
object whatever;
IComInterface casted = (IComInterface) whatever;
Hence, the following code, depending on the compiler and optimizations might trigger the QueryInterface
in the internal object casting implementation:
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;
Suppose I have a generic List<T>
instance:
List<IComInterface> list = new List<IComInterface>();
Now, do I have a strong guarantee that the following code would not trigger the QueryInterface
-based cast?
List<IComInterface> list = new List<IComInterface>();
IComInterface comInterface = (...); // Somehow got it.
list.Add(comInteface);
IComInterface retrieved = list[0];
Using ArrayList
instead of List<T>
here actually results in the cast performed, because you have to get the corresponding IComInterface
from your typeless object
instance.
However, in case of generics, I guess, everything should be done without casting, but I'm not actually sure about how they work under the surface.
Is it possible that List<T>
still somehow operates with object
types (and, hence, will invoke the QueryInterface
-based cast in the described scenario)?
If the answer to the previous question is "no", is it true, that you can't guarantee the same for any possible IList<T>
?
Yes, that's a pretty decent guarantee, the compiler won't emit a Opcodes.Castclass IL instruction unless it has to. The type matches so no need to for the cast.
This should not in general concern you. The QI implementation of a COM interface gets hammered for all kinds of reasons, internal to COM. It is always very fast, comparing a guid takes but a handful of nanoseconds.