Constructors and Initialization
A constructor is a special method, matching the class name and with no return type, that runs automatically whenever 'new' creates an instance. Its job is to bring the object into a valid, ready-to-use state — assigning required fields, validating arguments, wiring up dependencies, or acquiring resources. C# gives you several complementary tools for initialization: parameterized and parameterless constructors, constructor chaining (via 'this(...)' and 'base(...)'), field/property initializers, and object initializer syntax at the call site. Choosing the right combination keeps object construction both safe and expressive.
Cricket analogy: A constructor is like a player's pre-match warm-up routine that must run before he takes the field, ensuring stumps, gloves, and gear (fields) are ready, whether it's Virat Kohli batting or a debutant.
Defining constructors
If a class defines no constructor at all, the compiler supplies an implicit public parameterless one. As soon as you write any constructor yourself, that implicit one disappears, so if you still want a parameterless option you must declare it explicitly. Constructors can be overloaded like any method — multiple constructors distinguished by parameter list — letting callers construct an object in whichever way fits their situation.
Cricket analogy: If a team never names a captain, the board assigns a default one, but the moment the team appoints its own captain like Rohit Sharma, that default vanishes, and multiple captains can be named for different formats, just like overloaded constructors.
public class Rectangle
{
public double Width { get; }
public double Height { get; }
public Rectangle(double width, double height)
{
if (width <= 0 || height <= 0)
throw new ArgumentOutOfRangeException("Dimensions must be positive.");
Width = width;
Height = height;
}
// Chains to the primary constructor to avoid duplicating validation
public Rectangle(double side) : this(side, side) { }
}Constructor chaining with this and base
': this(...)' delegates to another constructor in the same class, useful for eliminating duplicated setup logic between overloads, as shown above with the square-shortcut constructor. ': base(...)' instead calls a constructor on the base class, which is essential in inheritance hierarchies: a derived class's constructor must ensure the base part of the object is initialized before the derived part runs. If you don't specify ': base(...)' explicitly, the compiler inserts an implicit call to the base class's parameterless constructor — which fails to compile if the base class has no such constructor available.
Cricket analogy: this(...) is like a net-practice routine reused for both spin and pace sessions, while base(...) is like a domestic player's national call-up requiring state-level trials (the base class) complete first before playing internationally.
public class Employee
{
public string Name { get; }
protected Employee(string name) => Name = name;
}
public class Manager : Employee
{
public int TeamSize { get; }
public Manager(string name, int teamSize) : base(name)
{
TeamSize = teamSize;
}
}Field initializers and object initializers
Fields and auto-properties can specify a default value inline ('private int _retries = 3;'); these run before the constructor body executes, in declaration order, for every constructor unless overwritten. Separately, object initializer syntax ('new Rectangle { ... }') lets a caller set accessible properties immediately after construction completes, which is handy for types with many optional settings — though it only works with settable properties (public set, init, or auto-properties), and the parameterless (or matching) constructor still runs first.
Cricket analogy: Default field values are like a stadium's standard pitch preparation done before any match-day toss, while object initializer syntax is like a broadcaster setting custom camera angles right after the toss but before play begins.
public class RequestOptions
{
public int TimeoutSeconds { get; init; } = 30;
public bool RetryOnFailure { get; init; } = true;
}
var options = new RequestOptions { TimeoutSeconds = 60 }; // RetryOnFailure stays true'init'-only setters (C# 9+) let object initializer syntax assign a property only during construction, then lock it — giving you the ergonomics of object initializers with the immutability of a readonly field, something Java typically only achieves via builder patterns.
Constructor chaining order can surprise you: base class field initializers and the base constructor body run BEFORE the derived class's field initializers and constructor body. If a base constructor calls a virtual method, it may execute on a derived object whose own fields haven't been initialized yet — a classic source of subtle bugs.
- A constructor shares the class name, has no return type, and runs on every 'new' call.
- An implicit public parameterless constructor exists only if you define no constructors at all.
- ': this(...)' chains to another constructor in the same class; ': base(...)' chains to the base class's constructor.
- Field/property initializers run before the constructor body, in declaration order.
- Object initializer syntax sets accessible properties right after construction, requiring settable (set/init) properties.
- Base class construction always completes before derived class construction begins.
Practice what you learned
1. What does C# provide automatically if a class defines no constructors at all?
2. What does ': this(a, b)' after a constructor signature do?
3. In an inheritance chain, when does the base class's constructor run relative to the derived class's constructor body?
4. What is required for a property to be settable via object initializer syntax ('new T { Prop = x }')?
5. When do field initializers execute relative to the constructor body?
Was this page helpful?
You May Also Like
Classes and Objects
Understand how C# classes define blueprints for reference-type objects, covering fields, methods, object creation, and the distinction between a class and its instances.
Inheritance in C#
Learn how C# classes derive from a single base class to reuse and extend behavior, including virtual/override methods, base member access, and sealing.
Properties and Indexers
Explore how C# properties expose controlled field access through get/set accessors, and how indexers let custom types support array-like `obj[key]` syntax.
Static Members
Learn how static fields, methods, and classes attach behavior and state to a type itself rather than to individual instances, and when that design choice makes sense.
Related Reading
Related Study Notes in Programming
Browse all study notesApache Spark Study Notes
Programming · 30 topics
ProgrammingApache Flink Study Notes
Programming · 30 topics
ProgrammingHadoop Study Notes
Programming · 30 topics
ProgrammingSnowflake Study Notes
Programming · 30 topics
ProgrammingApache Airflow Study Notes
Programming · 30 topics
Programmingdbt (Data Build Tool) Study Notes
Programming · 30 topics