C#
new statement
object initialization
programming
coding tips

What do braces after C new statement do?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

In C#, curly braces {} after a new statement are called initializer syntax. They allow you to set properties, fields, or add elements to collections in a single expression without calling explicit setters or Add() methods. There are three types: object initializers (new Person { Name = "Alice" }), collection initializers (new List<int> { 1, 2, 3 }), and dictionary initializers (new Dictionary<string, int> { ["key"] = 1 }). The compiler translates these into regular property assignments and method calls.

Object Initializer

Object initializers set public properties or fields immediately after construction:

csharp
1public class Person
2{
3    public string Name { get; set; }
4    public int Age { get; set; }
5    public string Email { get; set; }
6}
7
8// Without object initializer
9var person1 = new Person();
10person1.Name = "Alice";
11person1.Age = 30;
12person1.Email = "[email protected]";
13
14// With object initializer — equivalent to above
15var person2 = new Person
16{
17    Name = "Alice",
18    Age = 30,
19    Email = "[email protected]"
20};

The compiler translates the object initializer into a constructor call followed by property assignments. It creates a temporary variable, sets all properties, and then assigns it to the target variable.

With Constructor Parameters

You can combine constructor arguments and initializer syntax:

csharp
1public class Person
2{
3    public Person(string name) { Name = name; }
4    public string Name { get; set; }
5    public int Age { get; set; }
6}
7
8var person = new Person("Alice") { Age = 30 };
9// Equivalent to:
10// var temp = new Person("Alice");
11// temp.Age = 30;
12// var person = temp;

Nested Object Initializers

csharp
1public class Address
2{
3    public string City { get; set; }
4    public string Zip { get; set; }
5}
6
7public class Person
8{
9    public string Name { get; set; }
10    public Address Address { get; set; }
11}
12
13var person = new Person
14{
15    Name = "Alice",
16    Address = new Address
17    {
18        City = "New York",
19        Zip = "10001"
20    }
21};

Collection Initializer

Collection initializers add elements to any type that implements IEnumerable and has an Add() method:

csharp
1// List initialization
2var numbers = new List<int> { 1, 2, 3, 4, 5 };
3
4// Equivalent to:
5// var numbers = new List<int>();
6// numbers.Add(1);
7// numbers.Add(2);
8// ... etc.
9
10// HashSet
11var tags = new HashSet<string> { "csharp", "dotnet", "programming" };
12
13// List of objects
14var people = new List<Person>
15{
16    new Person { Name = "Alice", Age = 30 },
17    new Person { Name = "Bob", Age = 25 },
18    new Person { Name = "Charlie", Age = 35 }
19};

Custom Collection Initializer

Any class with Add() and IEnumerable works:

csharp
1public class Inventory : IEnumerable<string>
2{
3    private readonly List<string> _items = new();
4
5    public void Add(string item) => _items.Add(item);
6    public void Add(string item, int quantity)
7    {
8        for (int i = 0; i < quantity; i++) _items.Add(item);
9    }
10
11    public IEnumerator<string> GetEnumerator() => _items.GetEnumerator();
12    IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
13}
14
15// Multi-parameter Add method
16var inv = new Inventory
17{
18    { "Sword", 2 },    // Calls Add("Sword", 2)
19    { "Shield", 1 },   // Calls Add("Shield", 1)
20    "Potion"            // Calls Add("Potion")
21};

Dictionary Initializer

Classic Syntax (C# 3+)

csharp
1var scores = new Dictionary<string, int>
2{
3    { "Alice", 95 },
4    { "Bob", 87 },
5    { "Charlie", 92 }
6};
7// Calls: scores.Add("Alice", 95); scores.Add("Bob", 87); ...

Index Syntax (C# 6+)

csharp
1var scores = new Dictionary<string, int>
2{
3    ["Alice"] = 95,
4    ["Bob"] = 87,
5    ["Charlie"] = 92
6};
7// Calls: scores["Alice"] = 95; scores["Bob"] = 87; ...

The index syntax uses the indexer (this[]) instead of Add(). The difference matters because Add() throws on duplicate keys while the indexer overwrites.

Array Initializer

Arrays use similar syntax but without new Type[] in some cases:

csharp
1// Explicit
2int[] numbers = new int[] { 1, 2, 3 };
3
4// Implicit type
5var numbers = new[] { 1, 2, 3 }; // Compiler infers int[]
6
7// Target-typed (C# 12+)
8int[] numbers = [1, 2, 3];

Anonymous Types

Object initializer syntax is required for anonymous types:

csharp
1var result = new { Name = "Alice", Age = 30, IsActive = true };
2Console.WriteLine(result.Name); // Alice
3
4// Common in LINQ projections
5var names = people.Select(p => new { p.Name, NameLength = p.Name.Length });

with Expression (Records, C# 9+)

Records use with and braces for non-destructive mutation:

csharp
1public record Person(string Name, int Age);
2
3var alice = new Person("Alice", 30);
4var olderAlice = alice with { Age = 31 };
5// alice is unchanged, olderAlice has Age = 31

Common Pitfalls

  • Setting read-only properties in an initializer: Object initializers can only set properties with public setters (or init setters in C# 9+). Read-only properties or private setters cause a compile error. Use constructor parameters for read-only values.
  • Assuming initializer order is guaranteed: The C# specification guarantees that initializers execute in the order written, but relying on order (where one property depends on another) makes code fragile. Keep initializations independent.
  • Using collection initializer without Add method: The collection initializer syntax requires an Add method and IEnumerable implementation. A class with only Append() or Insert() will not work with { } syntax.
  • Confusing dictionary Add and indexer initializers: { "key", value } calls Add() and throws on duplicates. ["key"] = value calls the indexer and overwrites silently. Choose based on whether duplicates are an error or expected.
  • Mixing constructor and initializer for the same property: Setting a property in both the constructor and the initializer means the initializer wins (it runs after the constructor). This can hide bugs if the constructor value is intended to be final.

Summary

  • { } after new enables object initializers (set properties), collection initializers (add elements), and dictionary initializers
  • Object initializers compile to property assignments after the constructor call
  • Collection initializers call Add() for each element in the braces
  • Dictionary initializers support both { key, value } (Add) and [key] = value (indexer) syntax
  • Anonymous types and with expressions on records also use brace syntax

Course illustration
Course illustration

All Rights Reserved.