The Object type has existed since the beginning of C#, in other words C# 1.0 and exists at System.Object. Var comes next in C# 3.0 followed by the dynamic keyword in C# 4.0.
Object
Now object comes from C# 1.0 and derives from System.Object and we can assign any value to this reference.
- static void Main(string[] args)
- {
- object iobj = 10;
- var ivar = 10;
- dynamic dvar = 10;
- Console.WriteLine(iobj.GetType());
- Console.WriteLine(ivar.GetType());
- Console.WriteLine(dvar.GetType());
-
- 1)
- iobj = iobj + 10;
-
-
-
-
- iobj = (int)iobj + 10;
- Console.WriteLine(iobj);
- 2)
- ivar = ivar + 10;
-
-
- Console.ReadLine();
-
- 3)
- dvar = dvar + 10;
-
- Console.ReadLine();
- }
So what's the difference between var and dynamic?
- var was introduced in C# 3.0. Dynamic was introduced in C# 4.0.
- var is statically typed, in other words the data type of var is inferred at compile time. Dynamic is a dynamic type and the value type is inferred at runtime.
- Vars are initialized during declaration. A dynamic can be initialized at runtime.
- Var cannot be used to create a return type of a function or property. Dynamic can be used as the return type or properties.
- var cannot change the data type. A dynamic can change its data type later.
-
-
- dynamic dynam = 10;
- dynam = "string1";
- Console.ReadLine();
"As part of the process, variables of type dynamic are compiled into variables of type object. Therefore, type dynamic exists only at compile time, not at run time." -MSDN
The following are the usage of these two.
- They are used to reduce the number of lines of code. We do not need to write the type name again and again.
- Dictionary<string, Control> d = new Dictionary<string, Control>();
That can now be written simply as:
- var d = new Dictionary<string, Control>();
-
- dynamic d = new Dictionary<string, Control>();
- They are used extensively in anonymous methods. You wouldn't be able to declare a variable of an anonymous type if you always need to include the type name as part of the variable declaration.
- COM interop.
- Reading XML, JSON without creating custom classes.
Difference between object and dynamic
Dynamic tells the compiler that the data type can be anything so the compiler doesn't interfere and hence dynamic gives no compile-time error but will definitely give a runtime error is all is not good (in other words runtime error).
The following code will work properly for dynamic but not if dynamic is replaced by object. (The reason is explained in the preceding in the object type discussion.)
- dyn = 10.0;
- dyn = dyn + 10;
-
- dyn = "10";
- dyn = dyn + 10;
So if dynamic can take any data type, can we pass it to another function expecting something other data type and crash?
Assume we have a function:
- public static void display(string abc)
- {
- Console.WriteLine(abc);
- }
Now we have:
- object iobj = 10;
- display(iobj);
-
- dynamic dynam = 10;
- display(dynam);
- Console.ReadLine();
Here, the first one will not compile and the second one will compile but give a runtime error.
Dynamic suppresses the compiler logic.
With the dynamic keyword, one interesting object comes out to be
ExpandoObject.
In order to emulate the dynamic functionality of adding members to objects at runtime, .Net comes with the IDynamicMetaObjectProvider interface. Classes implementing it will have a full dynamic behavior.
A useful class in version 4 of the .NET Framework is ExpandoObject. It is a built-in implementation of the IDynamicMetaObjectProvider interface and it allows dynamically adding members at runtime, like in the following example:
- dynamic contact = new ExpandoObject();
- contact.Name = "GOGO";
- contact.Phone = "206-555-0144";
- contact.Address = new ExpandoObject();
- contact.Address.Street = "Main St";
The code is taken from MSDN. This has the following two interesting features.
- Here, we have not used ExpandoObject=new ExpandoObject () because doing so will make it a statically-typed object of the ExpandoObject type. And of course, statically-typed variables cannot add members at run time.
- To add another node to the contact node, simply add another ExpandoObject. (In other words contact.Address = newExpandoObject()).