Skip to content

Object and Collection Initializers

Object and collection initializers are syntax features that make instance setup shorter and easier to scan. They are common in configuration objects, data models, tests, and other scenarios where several values are assigned during creation.

Their main value is readability. They collect setup information into one visible block.

Object initializers

An object initializer assigns settable members after construction.

csharp
var user = new User
{
    Id = 10,
    Name = "Lina"
};

class User
{
    public int Id { get; set; }
    public string Name { get; set; } = string.Empty;
}

This is especially useful when a type has a parameterless constructor and several assignable properties.

How to think about them

mermaid
flowchart LR
    A["Create object"] --> B["Run constructor"]
    B --> C["Assign initializer members"]
    C --> D["Ready-to-use object"]

That means object initializers do not replace construction. They happen after the object has been created.

Why object initializers are useful

They help readers quickly see which values matter.

Compare this:

csharp
var settings = new AppSettings();
settings.Theme = "Light";
settings.Language = "en-US";
settings.PageSize = 20;

With this:

csharp
var settings = new AppSettings
{
    Theme = "Light",
    Language = "en-US",
    PageSize = 20
};

The second version makes the configuration easier to scan.

Collection initializers

Collection initializers add elements while the collection is being created.

csharp
var names = new List<string>
{
    "Lina",
    "Omid",
    "Sara"
};

This is clearer than creating the list and then calling Add repeatedly in many simple setup cases.

Combining object and collection initialization

These features can work together.

csharp
var order = new Order
{
    Id = 10,
    Items = { "Book", "Pen" }
};

class Order
{
    public int Id { get; set; }
    public List<string> Items { get; } = new();
}

Here the Order object is created, then Id is assigned, and items are added to the existing Items collection.

When initializers are a good fit

Initializers work especially well when:

  • the object has many optional settings
  • readability of setup is more important than procedural steps
  • the type exposes safe assignable properties
  • the object is essentially configuration or data setup

This is why they appear so often in tests, options objects, and data transfer models.

When constructors are better

If a value is required for a valid object, that requirement usually belongs in the constructor rather than only in an initializer.

For example, if a BankAccount cannot exist without an account number, the constructor should normally require it.

Initializers are great for optional configuration. Constructors are better for required validity rules.

A subtle but important point

Because object initializers run after construction, a parameterless constructor can temporarily create an incomplete object unless the type is designed carefully.

That is why object initializers should not be used to bypass strong invariants.

A fuller example

csharp
var dashboard = new DashboardOptions
{
    Title = "Sales Overview",
    RefreshSeconds = 30,
    Widgets =
    {
        "Revenue",
        "Top Products",
        "Regions"
    }
};

class DashboardOptions
{
    public string Title { get; set; } = string.Empty;
    public int RefreshSeconds { get; set; }
    public List<string> Widgets { get; } = new();
}

This setup is readable because the important information is the collection of chosen values.

Common beginner mistakes

  • Using object initializers for values that are truly required for validity.
  • Forgetting that the constructor runs before initializer assignments.
  • Overusing initializers when a small focused constructor call would be clearer.
  • Exposing writable properties only to support initialization when the type should really be more protected.

Summary

  • object initializers assign settable members after construction
  • collection initializers add elements during collection setup
  • they improve readability for configuration-style object creation
  • constructors are still better for required creation rules
  • initializers work best when they support clarity without weakening object validity

Practice

Rewrite a multi-line object setup using an initializer, then decide whether the result is genuinely clearer or whether constructor-based creation would better express required state.

As a second exercise, create one type where an initializer is the best fit and one type where constructor parameters are the better fit. Explain the difference in terms of optional versus required data.

Built with VitePress and published on GitHub Pages.