Deep C# - Dynamic C#
Written by Mike James   
Thursday, 16 January 2020
Article Index
Deep C# - Dynamic C#
Static Typing
Anonymous Typing
Dynamic typing
Overloading

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:

public class MyClass2:MyClass{
 public new string MyMethod(double f){
  return "Class2 Double";
 }
}

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:

MyClass MyObject = new MyClass2();

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.

 

Banner

 

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:

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

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:

excel.Cells[1,1].Value= “some string”

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.

csharp

Verdict

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.

 

More Information

Using Type dynamic

Related Articles

Data Typing Is A Relic  

Strong Typing

Type Systems Demystified

Late Binding - Myths and Reality

Deep C#

 Buy Now From Amazon

DeepCsharp360

 Chapter List

  1. Why C#?

    I Strong Typing & Type Safety
  2. Strong Typing
       Extract 
    Why Strong Typing ***NEW!
  3. Value & Reference
  4. Structs & Classes
  5. Inheritance
  6. Interfaces & Multiple Inheritance
  7. Controlling Inheritance

    II Casting & Generics
  8. Casting - The Escape From Strong Typing
  9. Generics
  10. Advanced Generics
  11. Anonymous & Dynamic

    Typing
    III Functions
  12. Delegates
  13. Multicast Delegates
  14. Anonymous Methods, Lambdas & Closures

    IV Async
  15. Threading, Tasks & Locking
  16. The Invoke Pattern
  17. Async Await
  18. The Parallel For

    V Data - LINQ, XML & Regular Expressions
  19. The LINQ Principle
  20. XML
  21. LINQ To XML
  22. Regular Expressions

    VI Unsafe & Interop
  23. Interop
  24. COM
  25. Custom Attributes
  26. Bit Manipulation
  27. Advanced Structs
  28. Pointers 

 <ASIN:1871962714>

 <ASIN:B09FTLPTP9>

square

 



 

Comments




or email your comment to: comments@i-programmer.info

 

<ASIN:1494208393>

<ASIN:0956575862>

<ASIN:1890774723>

<ASIN:1849696586>

<ASIN:0985580100>



Last Updated ( Thursday, 16 January 2020 )