var vs dynamic in C#
var and dynamic both let you declare a variable without writing its type, so they look similar,
but they work in completely different ways. With var the compiler decides the type at compile time, and
the variable is just as strongly typed as if you had written the type yourself. With dynamic the type is
decided at runtime, and the compiler skips type checking for that variable. This is one of the most frequently asked
C# interview questions, so this lesson explains both with examples, shows the errors each one produces, and ends with
the questions interviewers usually ask.
var: implicitly typed, compile-time type, checked by the compiler, introduced in C# 3.0.dynamic: runtime type, checked only when the code runs, introduced in C# 4.0.
What is var in C#?
var declares an implicitly typed local variable. The compiler looks at the value on the right-hand side
and uses that type. After compilation there is no difference between var and the explicit type: the
generated code is exactly the same, so there is no performance cost.
var count = 10; // compiler decides: int
var name = "Sudheer"; // string
var price = 499.99m; // decimal
var items = new List<string>(); // List<string>
Console.WriteLine(count.GetType()); // System.Int32
Console.WriteLine(name.Length); // 7 - IntelliSense shows all string members
Rules of var
- It must be initialised in the same statement, because the compiler needs a value to work out the type.
- It cannot be initialised with
null, becausenullhas no type. - Once the type is decided it cannot change: a
varholding anintcan never hold a string. - It can only be used for local variables, not for fields, method parameters or return types.
var a; // error CS0818: Implicitly-typed variables must be initialized
var b = null; // error CS0815: Cannot assign <null> to an implicitly-typed variable
var total = 100; // int
total = "hundred"; // error CS0029: Cannot implicitly convert type 'string' to 'int'
All of these mistakes are caught by the compiler, before the program ever runs. That is the biggest advantage of var.
What is dynamic in C#?
dynamic tells the compiler: "don't check this variable, work it out when the program runs."
Member calls on a dynamic variable are resolved at runtime by the Dynamic Language Runtime (DLR).
The variable can hold any type and can even change type later.
dynamic value = 10;
Console.WriteLine(value.GetType()); // System.Int32
value = "Hello MakeMyCodes"; // allowed: now it holds a string
Console.WriteLine(value.GetType()); // System.String
Console.WriteLine(value.Length); // 17 - resolved at runtime
value = new List<int> { 1, 2, 3 }; // now a list
Console.WriteLine(value.Count); // 3
Rules of dynamic
- It can be declared without a value and assigned later, like any normal variable.
- It can hold any type and change type at any time.
- It can be used for local variables, fields, properties, method parameters and return types.
- There is no IntelliSense after the dot, because Visual Studio does not know the type while you type.
- Mistakes are found only at runtime, as a
RuntimeBinderException.
Compile-Time Error vs Runtime Error
The clearest way to see the difference is to make the same mistake with both: calling a method that does not exist.
var text1 = "MakeMyCodes";
text1.Foo(); // error CS1061: 'string' does not contain a definition for 'Foo'
// -> the program does NOT compile
dynamic text2 = "MakeMyCodes";
text2.Foo(); // compiles successfully!
// -> at runtime: Microsoft.CSharp.RuntimeBinder.RuntimeBinderException:
// 'string' does not contain a definition for 'Foo'
With var the bug is found while you are coding. With dynamic it is found only when that line runs,
possibly in production. This is why dynamic should be used only when you really need it.
Using dynamic as a Parameter and Return Type
var cannot be used here, but dynamic can:
// var GetData() { ... } // error CS0825: The contextual keyword 'var' may only appear
// within a local variable declaration or in script code
static dynamic Add(dynamic a, dynamic b)
{
return a + b; // the "+" is decided at runtime
}
Console.WriteLine(Add(10, 20)); // 30 (int + int)
Console.WriteLine(Add("Make", "MyCodes")); // MakeMyCodes (string + string)
Console.WriteLine(Add(2.5, 1.5)); // 4 (double + double)
Differences Between var and dynamic
| Point | var | dynamic |
|---|---|---|
| Introduced in | C# 3.0 | C# 4.0 |
| Type decided at | Compile time | Runtime |
| Type checking | By the compiler | At runtime (DLR) |
| Errors found | Compile-time errors | Runtime exceptions (RuntimeBinderException) |
| Initialisation | Required in the declaration | Can be assigned later |
| Can change type | No | Yes |
| IntelliSense | Yes | No |
| Use as field, parameter or return type | No, local variables only | Yes |
| Performance | Same as an explicit type | Slower: runtime binding overhead |
| Typical use | LINQ, anonymous types, long type names | COM/Office interop, JSON, reflection |
var vs object vs dynamic
Interviewers often add object to this question. object can also hold any value, but you must cast it before using it:
object o = "Hello";
// Console.WriteLine(o.Length); // error CS1061: 'object' does not contain 'Length'
Console.WriteLine(((string)o).Length); // 5 - cast first
dynamic d = "Hello";
Console.WriteLine(d.Length); // 5 - no cast, checked at runtime
var v = "Hello";
Console.WriteLine(v.Length); // 5 - v is a string at compile time
| var | object | dynamic | |
|---|---|---|---|
| Type known at | Compile time | Compile time (as object) | Runtime |
| Cast needed to use members | No | Yes | No |
| Boxing for value types | No | Yes | Yes |
| Type safety | Full | Checked when you cast | Only at runtime |
When to Use var
- LINQ queries and anonymous types, where you cannot write the type name at all.
- Long generic types, to keep code readable:
var map = new Dictionary<int, List<string>>(); - Whenever the type is obvious from the right-hand side.
var employees = new List<Employee>
{
new Employee { Name = "Ravi", Salary = 50000 },
new Employee { Name = "Sita", Salary = 65000 }
};
// The result is an anonymous type - only var can hold it
var result = employees.Select(e => new { e.Name, Yearly = e.Salary * 12 });
foreach (var r in result)
Console.WriteLine($"{r.Name}: {r.Yearly}");
// Ravi: 600000
// Sita: 780000
When to Use dynamic
- COM interop, such as automating Excel or Word, where the API returns loosely typed objects.
- JSON or data with an unknown shape, for example
ExpandoObjector JSON.NET'sJObject. - Simplifying reflection code, or talking to dynamic languages such as IronPython.
dynamic student = new System.Dynamic.ExpandoObject();
student.Name = "Divyani"; // properties are created at runtime
student.Course = "Data Science";
student.Marks = 92;
Console.WriteLine($"{student.Name} - {student.Course} - {student.Marks}");
// Divyani - Data Science - 92
Best practice: use var freely in everyday code, and use dynamic only when the type genuinely
cannot be known at compile time. Overusing dynamic removes the compiler's safety net and makes code slower and
harder to maintain.
Interview Questions on var and dynamic
1. Is var strongly typed?
Yes. var is only a shortcut: the compiler replaces it with the real type, so the variable is fully strongly typed.
2. Why can't var be declared without a value?
Because the compiler decides the type from the value. Without a value (or with null) there is nothing to infer the type from.
3. Can a dynamic variable change its type?
Yes. It can hold an int and later a string or any object, because its type is resolved each time it is used.
4. Which is faster, var or dynamic?
var. It compiles to the same code as an explicit type, while every dynamic operation goes through runtime binding in the DLR.
5. What exception does dynamic throw for a wrong member?
Microsoft.CSharp.RuntimeBinder.RuntimeBinderException, at runtime, when the member does not exist on the actual object.
6. Can var be used as a method parameter or return type?
No. var is allowed only for local variables. dynamic can be used as a parameter, return type, field or property.
Summary
Choose var when you want shorter code with full compile-time safety and IntelliSense. Choose dynamic
only when the type is truly unknown until runtime, such as COM objects or JSON with an unknown structure, and accept that
errors will appear at runtime instead of compile time.