|Deep C# - Dynamic C#|
|Written by Mike James|
|Thursday, 16 January 2020|
Page 5 of 5
Overloading And Overriding
This can be slightly more complicated in that we can mix method overloading with overriding in a derived class - but the guiding principle still applies.
For example, suppose we have a derived class which overrides a non-virtual method in the original MyClass:
As the method isn't virtual you would expect early binding to be used i.e. based on the compile type type of the object. However we have already noted that using a dynamic parameter forces late binding. So which is it?
That is of we now change the creation of MyObject in the previous example to read:
which method will be used for a double MyClass's or MyClass2's?
At compile time the type of MyObject is MyClass even if at run time it actually refers to a MyClass2 object and so by the usual early binding rules it should be MyClass's methods that are used and indeed this is what happens - even though which MyClass method is called isn't determined until runtime.
Thus the method call is early bound to the class type but late bound according to the signature of the call.
However, if you change the method declarations to virtual and override late binding is used on them both and MyClass2's double method is called
This is ruthlessly logical and if you stop to think about it what really should happen in each case.
There are a number of other interesting but fairly esoteric “features” of dynamic but one final one worth mentioning is accessibility.
Currently all methods and properties have to be public to be dynamically accessible. This isn’t a huge problem but it means that you can’t call private methods from within a class using dynamic parameters even though without the dynamic parameters the call would be perfectly legal.
Similarly you can’t use extension methods dynamically – the information to implement them isn’t available at run time. Anonymous functions can’t appear as arguments to a dynamic method call for the same reason. This makes it difficult to use LINQ queries over dynamic objects, which is strange given that LINQ was and is a major motivation for C# becoming more dynamic.
Beyond plain .NET objects
How the method invocation or property access is handled depends on the type of object that the dynamic type references.
You might think that the only possibility is the plain old .NET object but part of the reason for introducing dynamic is to make externally derived objects easier to work with.
In the case of a standard .NET object reflection is used to dispatch the operation. This is more sophisticated than you might imagine because any dynamic objects passed as parameters are resolved using reflection and then the resulting signature combined with reflection is used to make call to the appropriate method.
Moving beyond plain .NET objects a new class of dynamic objects can customize how they behave by implementing the IDynamicObject interface.
In this case the task of working out which method or property is needed is handed off to the object itself to work out using any method that suits. This is the key to building truly dynamic object models that can respond in sophisticated ways.
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.
For example, consider the standard difficulty encountered in using the Office COM object model:
The cast has to be included because the PIA uses object types to represent variants. Using dynamic types in place of objects makes it possible to dispense with the cast and allow the run time system to work out what is legal:
Not using the PIA and driving the COM interface raw also means that you can hope to achieve a more efficient and lightweight program.
There are other minor enhancements to the way COM objects are dealt with in introduced in C# 4.0 that go together with dynamic types to make the whole thing easier to use.
For example, COM objects often pass parameters using pointers which result in the use of ref parameters in the corresponding C# methods. This can force you to create temporary variables to avoid any changes to a variable that you regard as logically being passed by value. Now the compiler will do the job for you by converting the value parameter to a temporary copy and passing this by reference.
The overall result is pass-by-value semantics for parameters that are passed as pointers.
Dynamic typing seems to be mostly harmless and it does improve the way that you can write some things that rely on determining type at runtime rather than compile time but it is a big change. It doesn't go as far as introducing a true dynamic approach to type but it is a change in philosophy.
Even if you regard it as an attempt to work with other systems that are less strict about type it is still a change that makes C# less pure and more ad-hoc.
Buy Now From Amazon
or email your comment to: firstname.lastname@example.org
|Last Updated ( Thursday, 16 January 2020 )|