3

from here

A very big advantage of dynamic types comes when you start to think about C#’s relationship with external and non-native objects – COM objects in particular. In this case a dynamic type is resolved using the COM IDispatch interface and this in turn means that you can use COM objects “raw”, i.e. without a Primary Interop Assembly (PIA). As many COM objects make extensive use of the variant type, which can store any of a number of standard data types, being able to use dynamic types in place of variants is a big simplification.

I already know how dynamic is used in C# , However - I want to know how it is done.(generally with COM)

looking at Office COM object model example :

(Excel.Range)excel.Cells[1,1]).Value= "some string"

The cast has to be included because the PIA uses object types to represent variants

Now (2010 ...), with dynamic it can be done with :

excel.Cells[1,1].Value= "some string"

But

An object can provide its binding semantics by implementing DynamicObject

such as :

public class MyClass: DynamicObject
{
  public override bool TryInvokeMember (  InvokeMemberBinder binder, object[] args, out object result)
    {
      ...
    }
}

So my question :

Did MS [changed] or [added code] or [now-inherit-DynamicObject] the COM objects in order to allow excel.Cells[1,1].Value= "some string" to work ?

Did they re-build this whole mechanism ?

3 Answers 3

6

No, the secret sauce is COM here. This is done with only 2 interfaces and 5 methods. The first one is IUnknown, an interface implemented by all COM objects. It has 3 methods:

  • AddRef(), increments the reference count on a COM object. This is a memory management function, as long as the count is non-zero the object stays alive. Storing a pointer to a COM object requires calling IUnknown.AddRef().

  • Release(), decrements the reference count. The opposite of AddRef and must be called when an interface pointer is no longer used. The COM object is released when the count reaches zero. This function is the core reason behind the rather infamous use of Marshal.ReleaseComObject() in .NET code that uses Office. It normally gets called by the finalizer of a COM wrapper.

  • QueryInterface(), asks the COM object to return a pointer to another interface. In the scope of this question, that's how C# gets the IDispatch interface pointer.

The IDispatch interface is the one that implements dynamic binding, the rough equivalent to DynamicObject. It has 4 methods, 2 of which are important in this context:

  • GetIDsOfNames(), converts a name to a number, a dispid. This is how an identifier in a C# program can be matched to a method or property name on the COM object.

  • Invoke(), calls the COM method of property getter/setter, using the dispid

That's the big picture, use the MSDN Library if you want to know more about these interfaces.

Sign up to request clarification or add additional context in comments.

2 Comments

There are some aspects I miss from the COM days...the all-powerful "QueryInterface" being one of them...
This is being added back to .NET 5: github.com/dotnet/runtime/pull/33060
2

The DLR (which is what the dynamic keyword offers interface to) uses "binders" to interface with the dynamic object proper (there is a C# binder, VB binder, COM binder etc.). The COM binder is a separate component that uses the "traditional" COM interop, which is not replaced and can still be used without dynamic. It was enhanced for .NET 4.0, but not just for dynamic.

Comments

1

You can use dynamic with any type. You need to derive from DynamicObject only when you want your classes to provide a dynamic interface.

The following line works, without requiring DateTime to inherit from DynamicObject:

dynamic myDate=DateTime.Now;

EDIT

As to how COM+ supports dynamic binding - it always did. In fact, the documentation explains exactly how this is done.

COM always supported its own kind of dynamic binding through the IDispatch interface which works roughly like DynamicObject. IDispatch allows an object to respond to queries for specific interfaces and the methods it supports.

dynamic can use the IDispatch interface for raw COM objects, where you don't have a type library or a proxy. In other cases, dynamic will call the proxy methods without going through the IDispatch interface.

Dynamic binding in COM introduces a performance hit, due to the multiple calls needed to extracta a specific interface and invoke its methods. In the VB6 days people tried to minimize or eliminate the use of dynamic binding by using type libraries. This is sound advice for .NET as well.

4 Comments

and this relates to com in........? (I know that dynamic leaves the execution to runtime)
I mean (like you said) MS wanted their classes also to provide a dynamic interface. so instead of (Excel.Range)excel.Cells[1,1]).Value= "some string" ---->excel.Cells[1,1].Value= "some string" my question is did they changed anything in order to allow that
See the edit. They didn't have to change anything, COM always supported dynamic binding through IDispatch
So for what this Idispatch was used before dynamic ?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.