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