Click here to Skip to main content
15,908,776 members
Articles / Programming Languages / C#

Dynamic Programming in C# 4.0 – An Overview

Rate me:
Please Sign up or sign in to vote.
3.86/5 (3 votes)
25 Feb 2010CPOL2 min read 19.1K   7   4
Introduction to dynamic programming in C# 4.0

One of the most interesting additions to C# 4.0, I think, is the dynamic addition. Just thinking about this makes me excited. I will jump right into a little theory, then some code.

The Theory of Dynamic

So what is this dynamic thingy? Dynamic in C# 4.0 refers to dynamic binding and dynamic binding is what happens at runtime and not at compile time. This involves binding a method, property, operator, member, etc. of an object at runtime. Yes, I know this sounds like polymorphism or like the var keyword or even like using the ultimate base class in C# – object. First and foremost, you have to let go of what you know and remember this important fact.

dynamic != var && dynamic != object

The keyword dynamic, casually speaking, tells the compiler that “Even though it cannot resolve the member statically, it should trust the programmer and not worry because it will/may be resolved at runtime.”

Code

Here is a sample on how you use the dynamic keyword:

C#
dynamic dyn = "My first time";
Console.WriteLine(dyn);

Now let’s look at some similarities and differences of var, object, and dynamic for a sec.

C#
var v = 1;     // here the compiler will figure out (at compile time)
       // the type for v which will be int.
Console.WriteLine(v.GetType().ToString());
//v.Compute();     // causes a compiler error
object o = 1;  // this is boxed from value type to an object with type being int32
Console.WriteLine(o.GetType().ToString());
//o.Compute();     //also gives a compiler error
dynamic d = 1;     //type here is int32
Console.WriteLine(d.GetType().ToString());
d.Compute();   // does not give compile time error but will throw a
       // runtime RuntimeBinderException

So How is this Binding Done?

Look at the following code:

C#
class Program
{
static void Main(string[] args)
{
dynamic dyn = "hello";
Function(dyn);     //The first call is slow because here the call site
       //must figure out the binding
Function(dyn);     //The second call is faster because all the binding lookup
       //was cached in the first call
Console.Read();
}

public static void Function(string s)
{
Console.WriteLine(s);
}

public static void Function(StringBuilder sb)
{
Console.WriteLine(sb.ToString());
}
}

Which version of Function is called? The one with the string argument.
The call to Function above on the dynamic type is resolved at runtime based on the runtime type information and not on the compile time’s type information. Also, the function with the most specific or closest matching parameter will be the one that is called. Pretty neat, huh? By the way, the way in which we used the dynamic keyword above is referred to as language binding.

A Bit More Advance Stuff

So let’s say you want to develop a class that is able to calculate some basic statistics and one of your key requirements is to make it so that the calls to the methods are case insensitive. Also, you want to be able to add new functionality at will. How can you do that?
In the System.Dynamic namespace, there is a class called DynamicObject that implements IDynamicMetaObjectProvider. If you want your classes to have the dynamic capability, then inheriting this class gives you those capabilities. By the way, inheriting DynamicObject or implementing IDynamicMetaObjectProvider is called custom binding.

C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Dynamic;

namespace OliverCode.DynamicProgramming
{
 public class Statistics : DynamicObject
 {
 private readonly double[] _arrayOfValues;

 public Statistics(double[] arrVals)
 {
 _arrayOfValues = arrVals;
 }

 public override bool TryInvokeMember(InvokeMemberBinder binder, 
				object[] args, out object result)
 {
 bool isSuccess = true;

 switch (binder.Name.ToLower())
 {
 case "average":
 result = _arrayOfValues.Average();
 break;
 case "max":
 result = _arrayOfValues.Max();
 break;
 case "min":
 result = _arrayOfValues.Min();
 break;
 default:
 result = 0;
 isSuccess = false;
 break;
 }

 return isSuccess;
 }
 }

 class Program
 {
 static void Main(string[] args)
 {
 dynamic stats = new Statistics(new double[] 
			{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 });

 Console.WriteLine(stats.max()); 	//resolved at compile time
 Console.WriteLine(stats.Max());	//resolved at compile time
 Console.WriteLine(stats.Mean());	//resolved at compile time

 Console.Read();
 }
 }
}

Pay attention to TryInvokeMember method that is overridden. This means that my class can handle method calls. Actually there are a few methods that you can override:

C#
IEnumerable<string> GetDynamicMemberNames();
DynamicMetaObject GetMetaObject(Expression parameter);
bool TryBinaryOperation(BinaryOperationBinder binder, object arg, out object result);
bool TryConvert(ConvertBinder binder, out object result);
bool TryCreateInstance(CreateInstanceBinder binder, object[] args, out object result);
bool TryDeleteIndex(DeleteIndexBinder binder, object[] indexes);
bool TryDeleteMember(DeleteMemberBinder binder);
bool TryGetIndex(GetIndexBinder binder, object[] indexes, out object result);
bool TryGetMember(GetMemberBinder binder, out object result);
bool TryInvoke(InvokeBinder binder, object[] args, out object result);
bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result);
bool TrySetIndex(SetIndexBinder binder, object[] indexes, object value);
bool TrySetMember(SetMemberBinder binder, object value);
bool TryUnaryOperation(UnaryOperationBinder binder, out object result);

I don’t have the details on all the methods but you get the gist.

So when does dynamic not work?

As far as I know, there are 3 cases in which dynamic doesn’t work:

  1. On interface members that are explicitly implemented
  2. With Extension methods
  3. Classes that subclass a base class, but hide the base classes members

So there is your introduction to dynamic programming. Happy coding and don’t forget to live.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) 4CoreDev
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralNice article... but... Pin
Nickolay Karnaukhov2-Mar-10 0:15
Nickolay Karnaukhov2-Mar-10 0:15 
Don't want to say anything bad about your article but just wanted to add a comment about "dynamic" in general.

I think this THING is worst addition ever.

"Trust programmer" is worst case in programming. Programmer is a human a makes mistakes. CPU->Machine code->C Kernel code->.NET Core->.NET program is quite a strong chain of tested and verified code where each line of code, each undeclared variable on any level can cause any kind of problems with security, stability and performance.

So my personal opinion is "Compiler should never trust programmer" as compiler is the only "not human" element (which is actually made by human but without any trust to programmer and with crazy QA process).

C# isn't script language like Ruby (from where this feature has been "assigned" to C#) and it is positioned as C/C++ replacement, more secure, more stable. But, in fact - Microsoft is giving so huge gift for lazy / stupid / unqualified programmers, which WILL lead to weak, unstable and unreliable software.

I know - you'll say it depends on programmer but facts are facts - programmers are humans and they make mistakes.

Personally - I prefer more strongly controlled languages like C# was before its 3.0 version.

Please comment if you disagree, because I would like to clarify this all for myself.

If I'm wrong - I'll agree Smile | :)
------------------------------------------------------------
Want to be happy - do what you like!

GeneralRe: Nice article... but... Pin
tec-goblin2-Mar-10 3:37
tec-goblin2-Mar-10 3:37 
GeneralRe: Nice article... but... Pin
S.H.Bouwhuis2-Mar-10 5:27
S.H.Bouwhuis2-Mar-10 5:27 
GeneralRe: Nice article... but... Pin
Nickolay Karnaukhov2-Mar-10 6:26
Nickolay Karnaukhov2-Mar-10 6:26 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.