views:

77

answers:

4

What is the difference between a variable declared as dynamic and a variable declared as System.Object? Running the following function would seem to indicate that both variables get cast to the correct type dynamically:

void ObjectTest()
{
    System.Object MyTestVar = "test";
    dynamic MyTestVar2 = "Testing 123";

    Console.WriteLine("{0}", MyTestVar.GetType());
    Console.WriteLine("{0}", MyTestVar2.GetType());

    MyTestVar = 123;
    MyTestVar2 = 321;

    Console.WriteLine("{0}", MyTestVar.GetType());
    Console.WriteLine("{0}", MyTestVar2.GetType());
}
+4  A: 

The difference is that MyTestVar2.ToUpper() compiles and works, without any explicit casting.

object is a normal type.
dynamic is a basically a placeholder type that causes the compiler to emit dynamic late-bound calls.

GetType() is a normal function defined by the object class that operates on the instance that you call it on.
GetType() is completely unaffected by the declared type of a variable that refers to the object you call it on. (except for nullables)

SLaks
so what you are saying is that you can call object-specific methods on dynamic variables?
icemanind
You can call _any_ method on `dynamic` variables. The code `dynamic x = 3; x.Explode();` will compile perfectly fine
SLaks
A: 

You should probably start with this excellent MSDN article. The differences can be summed up quite succinctly:

At compile time, an element that is typed as dynamic is assumed to support any operation.

System.Object only has a handful of operations that it supports - ToString(), Equals(), etc.

Igor Zevaka
A: 

The fundamental difference is compile-time(for object) vs runtime (for dynamic) resoulution of calls. Its also called early vs late binding. [ Note: add a reference to Microsoft.CSharp for the following code to compile.]

   object o = "Hello world";// fine because a derived type can be assigned to a base type
   dynamic d= "Hello world";// fine as well  

   Type otype=o.GetType();// compiles because it confirms that object has a GetType()
   Type dtype=d.GetType();// also compiles but for another reason (i.e.no binding yet)

   string upperd= d.ToUpper(); // compiles because no binding yet ( anything goes :)
   string uppero= o.ToUpper(); // Fails to compile. Object has no ToUpper() method 

If you comment out the last call , the application should run fine because the CLR , when it reaches the second last call d.ToUpper() at runtime, it will look for a method ToUpper() in the string type and will find it there (because in the second statement d was assigned a string). The last call did not compile because ToUpper() was being searched in the System.Object type at the compile time which of course will not be there.

mumtaz