As we bid farewell to the older syntax, let’s embrace the newer, more expressive way of creating objects.
Introduction
In C# 12, primary constructors play a crucial role in defining the behaviour of classes and structs. By adding parameters to a struct or class declaration, you can create a primary constructor.
Use Cases
Base Constructor Invocation: Pass primary constructor parameters as arguments to a base constructor invocation. This allows for seamless initialization of base class properties.
Member Field Initialization: Primary constructor parameters are often used to initialize member fields or properties. By directly assigning values during construction.
Getting Started
The struct & constructor declaration before C# 12. Please find below the example of the older syntax.
public readonly struct Distance
{
public readonly double Magnitude { get; }
public readonly double Direction { get; }
public Distance(double dx, double dy)
{
Magnitude = Math.Sqrt(dx * dx + dy * dy);
Direction = Math.Atan2(dy, dx);
}
}
Newer Syntax
Consider the following example, let's create a struct namedDistance with two primary constructor parameters: dx and dy. Later we can compute two read-only properties—Magnitude and Direction—based on these parameters:
public readonly struct Distance(double dx, double dy)
{
public readonly double Magnitude { get; } = Math.Sqrt(dx * dx + dy * dy);
public readonly double Direction { get; } = Math.Atan2(dy, dx);
}
Invoking Base Class Primary Constructors
Primary constructors can be leveraged in inheritance hierarchies. When a derived class has its primary constructor, it can invoke the base class’s primary constructor using the base keyword.
Example: Bank Account Hierarchy
Consider a base class BankAccount with a primary constructor for account number and initial balance:
public class BankAccount(int accountNumber, decimal initialBalance)
{
// Additional initialization specific to SavingsAccount
// ...
}
Now, a derived class SavingsAccount can inherit from BankAccount and invoke its primary constructor as shown below
public class SavingsAccount(int accountNumber, decimal initialBalance) : BankAccount (accountNumber, initialBalance)
{
// Additional initialization specific to SavingsAccount
// ...
}
Custom Behavior in Derived Classes
Derived classes can further customize their behaviour within the constructors. For instance, a CheckingAccount class might inherit from BankAccount but invokes the base constructor using base keyword
public class CheckingAccount : BankAccount
{
public CheckingAccount(int accountNumber, decimal initialBalance)
: base(accountNumber, initialBalance)
{
// Additional initialization specific to CheckingAccount
// ...
}
}
Conclusion
In the ever-evolving landscape of programming languages, C# 12 introduces a powerful feature: primary constructors. These concise and elegant constructs allow us to define the behaviour of classes and structs with utmost clarity.
As we bid farewell to the older syntax, let’s embrace the newer, more expressive way of creating objects.
C# Programming🚀
Thank you for being a part of the C# community! Before you leave:
If you’ve made it this far, please show your appreciation with a clap and follow the author! 👏️️
Follow us: X | LinkedIn | Dev.to | Hashnode | Newsletter | Tumblr
Visit our other platforms: GitHub | Instagram | Tiktok | Quora | Daily.dev
More content at C# Programming
Top comments (2)
Thanks, even though I'm not a huge fan of primary constructors, at least in classes, because in records I like them a lot, it's a really interesting article for understanding how them work.
thanks @ssukhpinder !
Thanks @xaberue i'm glad that the article is helpful for you.