Roadmap › C# Language — Basics to Advanced › Module: Types in Depth
Lessons in this course (38)

19. var, object initializers, anonymous types and dynamic

Basic★ Must knowLesson 19 of 38

var (implicitly typed local, C# 3): the compiler infers the type from the right-hand side; the variable is still statically typed.

csharp
var count = 10;                 // int
var customers = new List<Customer>();
// var x;                       // error — must be initialised
// var y = null;                // error — no type to infer
count = "ten";                  // error — count is int forever

Use var when the type is obvious from the right side or very long; write the type when it helps the reader (decimal total = GetTotal();).

Object and collection initializers: set properties right after construction without writing many constructors.

csharp
var c = new Customer { Id = 1, Name = "Asha", Address = new Address { City = "Pune" } };
var cities = new List<string> { "Pune", "Taipei" };
var phoneBook = new Dictionary<string, string> { ["Asha"] = "98200", ["Ravi"] = "98300" };
Customer c2 = new() { Name = "Ravi" };       // target-typed new (C# 9)

The constructor runs first, then each property setter in order. Combine with init / required properties for immutable objects that must be fully initialised.

Anonymous types: read-only, compiler-generated classes without a name — mainly for LINQ projections inside one method.

csharp
var person = new { Name = "Asha", Age = 28 };
Console.WriteLine(person.Name);
// person.Age = 30;             // error — properties are read-only
var summary = orders.Select(o => new { o.Id, Total = o.Lines.Sum(l => l.Price) });   // property names inferred
Console.WriteLine(new { A = 1 }.Equals(new { A = 1 }));   // True — value equality

Limits: only usable with var (no type name), can't be returned from a method in a typed way (use a record or tuple instead), properties only.

dynamic (C# 4): type checking moves from compile time to runtime (Dynamic Language Runtime).

csharp
dynamic d = 10;
d = "now a string";               // allowed
Console.WriteLine(d.Length);      // resolved at runtime → 12
// d.NoSuchMethod();              // compiles, but throws RuntimeBinderException at runtime

dynamic bag = new ExpandoObject();   // add members at runtime
bag.Name = "Asha";
bag.Greet = (Func<string>)(() => $"Hi {bag.Name}");
Console.WriteLine(bag.Greet());      // used for COM interop (Office), dynamic languages, loose data
varobjectdynamic
Type decidedCompile time (inferred)Compile time (object)Runtime
IntelliSense / compile errors✅Only object members❌
Needs castingNoYesNo
PerformanceNormalBoxing for value typesSlower (runtime binding)

Interview tip: "Is var the same as dynamic?" — No. var is just shorthand; the compiler fixes the type at compile time. dynamic skips compile-time checks and binds at runtime, so mistakes become runtime exceptions.