Var versus Dynamic
02 Jun 2013Both look similar but the inner differences are so many. var is resolved at compile-time whereas dynamic is resolved at runtime. var
was introduced in C# 3.0, and dynamic
was introduced in C# 4.0
When you use var
, the C# compiler tries to figure out the data type from the right-hand side expression.
var s = "string"; // The static type is string, and the runtime type is also string
The compiler will map this into:
string s = "string";
var
is intended to improve readability and save you keystrokes. It is not recommended to use var for primitive data types (int, string, etc.) since it might introduce confusion. var is commonly used with LINQ as the return data type is a little long to type (IEnumerable<T>
).
dynamic
tells the compiler to ignore checking the variable at compile-time and wait until runtime.
dynamic x ="string"; // The static type is dynamic, but the runtime type is string
Console.WriteLine(x.GetType()); // Runtime type is (String)
x = 100;
Console.WriteLine(x.GetType()); // Runtime type is (Int32)
Note that you could change the data type of a dynamic variable at runtime.
Because dynamic binding defers resolving from compile-time to runtime, it is possible to get runtime errors if something goes wrong:
dynamic x ="string";
x++; // RuntimeBinderException
The previous code compiles fine but throws a runtime exception.
Dynamic binding is useful when working with dynamic languages such as IronPython and IronRuby. It is also used in COM and sometimes in Reflection.
You can also do more exciting things with dynamic binding:
dynamic department = new ExpandoObject();
department.Name = "ABC";
department.Company = "My Company";
Console.WriteLine("Name: {0}", department.Name); // Name: ABC
Console.WriteLine("Company: {0}", department.Company); // Company: My Company
Notice that we haven’t declared any of the properties Name or Company. The C# magic above works because the properties are added at runtime and stored in a dictionary:
var dict = department as IDictionary<string, object>;
foreach (string key in dict.Keys)
Console.WriteLine("{0}: {1}", key, dict[key]);
// Output:
// Name: ABC
// Company: My Company
If you are an ASP.NET MVC developer, you may have noticed a similar feature with the ViewBag
object. ViewBag is in fact a dynamic object that wraps ViewData
.
ViewBag.Content = "Sample data";
// ViewData["Content"] also contains "Sample Data"
Another common use for var is to create anonymous types. An anonymous type is a class generated by the C# compiler.
To create an anonymous type, use the keyword new
and the object initializer:
var person = new { Name = "Adam", Age = 30 };
The compiler generates the following class (approximately)
internal sealed class f__AnonymousType0
{
private string name;
private int age;
public f__AnonymousType0(string name, int age)
{
this.name = name; this.age = age;
}
public string Name { get { return name; } }
public int Age { get { return age; } }
// Overridden methods here ...
}
The real class looks almost unreadable but has the same structure. Also, if two similar (same property names and data types) anonymous types are declared within the same assembly, the compiler reuses the same class for both:
var adam = new { Name = "Adam", Age = 25 };
var mike = new { Name = "Mike", Age = 32 };
Console.WriteLine(adam.GetType() == mike.GetType()); // True
Even the following is true:
var adam = new { Name = "Adam", Age = 25 };
dynamic mike = new { Name = "Mike", Age = 32 };
Console.WriteLine(adam.GetType() == mike.GetType()); // True
The previous holds true because mike at runtime has the same data type as adam.
Compare the following:
Console.WriteLine(adam.LastName); // Compile-time error. No such property
Console.WriteLine(mike.LastName); // Runtime error