Difference Between var and dynamic in C
In C#, both var and dynamic allow
developers to declare variables without explicitly naming their
underlying types, but they operate on fundamentally different
mechanisms. The var keyword introduces compile-time type
inference, meaning the compiler detects and locks in the type before
your code runs. Conversely, the dynamic keyword defers all
type checking and member resolution to runtime via the Dynamic Language
Runtime (DLR). This article breaks down how each keyword functions,
compares their key behaviors, and highlights when to use each in your
applications.
Understanding the
var Keyword
Introduced in C# 3.0, var provides implicit typing for
local variables. When you declare a variable with var, the
C# compiler evaluates the right-hand side of the assignment expression
and determines the exact data type at compile time.
var number = 42; // The compiler compiles this as: int number = 42;
var message = "Hello"; // The compiler compiles this as: string message = "Hello";Because var is resolved during compilation:
- It is strongly typed: Once initialized, the
variable's type cannot change. Assigning a string to an integer declared
with
varresults in a compilation error. - Mandatory initialization: You must initialize the
variable immediately so the compiler can infer its type. You cannot
write
var x;. - Tooling support: Full IntelliSense and code refactoring features are preserved.
- Scope limitation: It can only be used for local variables inside methods, loops, or using blocks. It cannot be used for class fields, method parameters, or return types.
Understanding the
dynamic Keyword
Introduced in C# 4.0, dynamic disables compile-time type
checking. Instead, operations on dynamic variables are evaluated at
runtime using the Dynamic Language Runtime (DLR).
dynamic value = 42; // Type is resolved as System.Int32 at runtime
value = "Hello World"; // Perfectly valid: type changes to System.String at runtimeKey characteristics of dynamic include:
- Runtime binding: The compiler does not verify
whether properties or methods exist on a dynamic object. If an invoked
member does not exist, a
RuntimeBinderExceptionis thrown during execution. - Optional initialization: Dynamic variables do not need to be initialized at declaration.
- Loss of compile-time tooling: Visual Studio cannot provide reliable IntelliSense, auto-completion, or static analysis for dynamic members.
- Versatile scope: Unlike
var,dynamiccan be used as a method parameter, method return type, field, or property on a class.
Key Differences at a Glance
| Feature | var |
dynamic |
|---|---|---|
| Type Resolution | Compile-time | Runtime |
| Type Safety | Fully static and strongly typed | Bypasses static type checks |
| Reassignable to Other Types | No | Yes |
| IntelliSense Support | Yes | No |
| Performance | Native execution speed; no overhead | Minor overhead due to DLR lookup |
| Usage Placement | Local variables only | Locals, fields, parameters, and returns |
| Initialization | Must be initialized at declaration | Can be declared without initialization |
When to Use var vs.
dynamic
Use var when:
- Working with complex types (e.g.,
Dictionary<string, List<Customer>>) to improve code readability. - Consuming LINQ queries and anonymous types where the type name is either long or unnamable.
- You still want full static type safety, performance, and compile-time error detection.
Use dynamic when:
- Interoperating with COM APIs (such as Microsoft Office automation).
- Interacting with dynamic languages on the .NET framework (e.g., IronPython).
- Handling loosely structured data payloads, such as dynamic JSON or XML documents, without defining strict C# models.
- Building advanced reflection wrappers where method names are determined during execution.