Search code examples
c#comcastingqueryinterface

C# - <T> object casting


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;

Q:

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>?


Solution

  • 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.