Dynamic Programming Using C# 4.0 and Microsoft Visual Studio 2010

Introduction

C# 4.0 introduces flexible and declarative style of programming by using the dynamic language runtime library (DLR). This style is called dynamic programming. Dynamic programming might not be new to you if you are a C++, Python or Ruby developer. Programmers can now use the 'Dynamic' keyword (the new static type) for creating typed objects or placeholders. These dynamic type objects bypass compile-time type checking that's why types of these placeholders are unknown until runtime. In .NET framework 4.0 architecture DLR is built on top of CLR (common language runtime) to support dynamism of dynamic programming languages like Python and Ruby . In this article I will show how you can create dynamic objects using the 'Dynamic' keyword.

How to Use Dynamic

Let me first show you some code snipped from a dynamic type declaration. You just need to declare a variable whose static type is dynamic. As I have already discussed above, dynamic is typed objects or placeholders (like var in Visual Basic) that indicates the compiler that object type will be resolved dynamically.

  dynamic objdynamic = "Dynamic Programming Sample";  
  dynamic objstring = objdynamic;  
  dynamic objint = 1;
  dynamic objlist = new List<int> { 1, 2, 3 };

In the above example type of 'objstring' object will be System.String at run-time. You can also assign a return value of any method to dynamic objects. The following code snippet demonstrates:

  static void Main ( string[] args )
  {
  dynamic objdynamic = GetDynamicObject();
  }
   
  public static int GetDynamicObject ( )
  {
  int i = 3;
  int j = 4;
  return i+j;
  }

Now let me show you few examples of RuntimeBindingException that can occur while working with a dynamic static type.

  dynamic dynullvalue = null;
  dynamic objtype = dynullvalue.GetType ( );

The above code will work in compile time but will throw an exception in runtime as the 2nd statement is trying to access type of null reference. Dynamic objects can't perform object binding on null reference.

  dynamic objdynamic = "Dynamic Programming Sample";
  int i = objdynamic;

The above code will throw an implicit conversion error in runtime (string can't be converted to integer). Dynamic will also throw runtime exceptions for non existing property or method. The following code snippet will throw RuntimeBindingException for the same reason.

    dynamic objdynamic = "Dynamic Programming Sample";
    int i = objdynamic.Intvalue;   // Property doesn't exists
    int j = objdynamic.GetIntValue ( ); // Method doesn't exists
 

Now let me show you a working example dynamic keyword. For creating the sample C# programming console application I have used Microsoft Visual Studio 2010 Ultimate Edition with .NET framework 4.0. First I have created a currency conversion class with 1 method named ConvertCurrency(). This ConvertCurrency() method converts source currency to destination currency type using a conversion factor. The following is a code snippet of the CurrencyConvert class.

   public class CurrencyConvertionService : ICurrencyConvertionService
           {
          
    public double ConvertCurrency ( string fromcurrency, string tocurrency,   
           double amount )
               {
               if ( fromcurrency.Length <=0 || tocurrency.Length <= 0 )
                   return 0;
               if ( amount <=0 )
                   return 0;
   
               switch ( fromcurrency )
                   {
                   case "INR":
                       if ( tocurrency.Trim ( ).ToString ( ) == "USD" )
                           return amount * 0.0214938;
                       if ( tocurrency.Trim ( ).ToString ( ) == "EUR" )
                           return amount * 0.0175683;
                       if ( tocurrency.Trim ( ).ToString ( ) == "GBP" )
                           return amount * 0.0145759;
                       break;
                   case "USD":
                       if ( tocurrency.Trim ( ).ToString ( ) == "INR" )
                           return amount * 45.67;
                       if ( tocurrency.Trim ( ).ToString ( ) == "EUR" )
                           return amount * 0.817748;
                       if ( tocurrency.Trim ( ).ToString ( ) == "GBP" )
                           return amount * 0.678214;
                       break;
   
                   case "GBP":
                       if ( tocurrency.Trim ( ).ToString ( ) == "INR" )
                           return amount * 68.5929;
                       if ( tocurrency.Trim ( ).ToString ( ) == "EUR" )
                           return amount * 1.20610;
                       if ( tocurrency.Trim ( ).ToString ( ) == "USD" )
                           return amount * 1.47431;
                       break;
                   default:
                       return 0;
   
                   }
               return 0;
   
               }
           }
 

Next I have written the main() method to show how both static CurrencyConvert class object and dynamic object works. For both the cases you will get an identical converted value if you are passing the same input parameters. Main() method code example is shown below:

   class Program
           {
           static void Main ( string[] args )
               {
               CurrencyConvert objConverter = GetConverter ( );
               Console.WriteLine(  objConverter.ConvertCurrency ( "USD", "INR", 50 ));
               Console.Read ( );
               // Dynamic 
               dynamic dyobjConverter = GetConverter ( );
               Console.WriteLine ( dyobjConverter.ConvertCurrency ( "USD", "INR", 50 ) );
               Console.ReadLine ( );
               }                
           public static CurrencyConvert GetConverter ( )
               {
               CurrencyConvert objConverter = new CurrencyConvert ( );
               return objConverter;
               } 
    
           }
 

Dynamic and Overloading of Methods

In case of overloaded methods; runtime resolves which function needs to be called based on input parameter data type. To demonstrate the runtime resolution of dynamic objects I have created a calculator class with 2 overloaded versions of add method. Following is the code snippet from my calculator class.

    class Calculator
           {
           public double Add ( int i, double j )
               {
               return i+j;
               }
           public double Add ( int i, int j )
               {
               return System.Convert.ToDouble( i+j );
               }
 

Next I have written the following code section in the main() method to call both the add methods dynamically.

   static void Main ( string[] args )
               {
               Calculator objcal = new Calculator ( );
               dynamic myDynamic =  GetIntValue ( );
               dynamic myDynamic1 =  GetDoubleValue ( );
               Console.WriteLine( objcal.Add ( myDynamic, myDynamic1 ));
               Console.ReadLine ( );
    
               dynamic myDynamic2 =  GetIntValue ( );
               dynamic myDynamic3 =  GetIntValue ( );
               Console.WriteLine ( objcal.Add ( myDynamic2, myDynamic3 ) );
               Console.ReadLine ( );
    
               }                
           public static int GetIntValue ( )
               {
               return 10;            
               }
           public static double GetDoubleValue ( )
               {
               return 10.25;
               }
 

The 1st Add method invocation by objcal.Add ( myDynamic, myDynamic1 ) statement calls up Add ( int i, double j ) overloaded method of calculator class as dynamic input parameter types are integer and double. Similarly the 2nd Add method invocation by objcal.Add ( myDynamic2, myDynamic3 ) statement calls up Add ( int i, int j ) an overloaded method of calculator class for the matching input parameters data type.

Conclusion

Using dynamics, developers can now make interop calls. You can also call COM object's method using dynamic. Dynamic keyword can be used to replace complicated reflection code you have already written but there are also a few limitations. For example, you can't call extension methods and anonymous functions.

Related Articles





Comments

  • There are no comments yet. Be the first to comment!

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Live Event Date: September 16, 2014 @ 11:00 a.m. ET / 8:00 a.m. PT Are you starting an on-premise-to-cloud data migration project? Have you thought about how much space you might need for your online platform or how to handle data that might be related to users who no longer exist? If these questions or any other concerns have been plaguing you about your migration project, check out this eSeminar. Join our speakers Betsy Bilhorn, VP, Product Management at Scribe, Mike Virnig, PowerSucess Manager and Michele …

  • Not long ago, security was viewed as one of the biggest obstacles to widespread adoption of cloud-based deployments for enterprise software solutions. However, the combination of advancing technology and an increasing variety of threats that companies must guard against is rapidly turning the tide. Cloud vendors typically offer a much higher level of data center and virtual system security than most organizations can or will build out on their own. Read this white paper to learn the five ways that cloud …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds