Initializing Auto-Properties in C#: TOP-5 Mistakes and Master Class

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Introduction: Why Did the Question About Auto-Properties Gather Thousands of Views?

\n\n

If you've ever written in C#, you've likely encountered a simple but important question: "How to correctly set an initial value for an auto-property?". This question on Stack Overflow has gathered tens of thousands of views, and for good reason. The apparent simplicity hides many pitfalls.

\n\n

Imagine: you create a User class, and you want the Name property to default to an empty string, not null. What could go wrong, you might think? But in practice, developers make typical C# property initialization mistakes that lead to NullReferenceException or non-obvious behavior.

\n\n

In this article, we'll break down the TOP-5 mistakes and show you how to avoid them. You'll learn modern approaches—from C# 6 to C# 12—and understand which method to choose for your project.

\n\n
\n\n

Mistake #1: Ignoring Auto-Property Initialization

\n\n

The most common mistake is not setting an initial value for reference types. Many beginners write:

\n\n
public class User\n{\n    public string Name { get; set; } // null by default\n    public List<string> Roles { get; set; } // null\n}
\n\n

In C#, auto-properties for reference types default to null. This leads to NullReferenceException issues when you forget to assign a value before use.

\n\n

How to Fix?

\n

Always explicitly set a C# auto-property initializer. The simplest way is to use C# 6 syntax:

\n\n
public class User\n{\n    public string Name { get; set; } = string.Empty;\n    public List<string> Roles { get; set; } = new List<string>();\n}
\n\n
\n

Tip: Use string.Empty instead of empty quotes—this improves readability and follows C# best practices.

\n
\n\n
\n\n

Mistake #2: Initialization in the Constructor Without Considering the Call Chain

\n\n

Another common mistake is setting the C# default value only in the constructor, while ignoring property initializers. This can lead to confusion, especially with inheritance.

\n\n
public class BaseClass\n{\n    public int Value { get; set; }\n\n    public BaseClass()\n    {\n        Value = 10;\n    }\n}\n\npublic class DerivedClass : BaseClass\n{\n    public DerivedClass()\n    {\n        // Value is already = 10, but we can overwrite it\n    }\n}
\n\n

The problem: if you add an initializer to the Value property and keep the assignment in the constructor, the execution order may surprise you. Initializers run before the base class constructor body, but after the derived class constructor call.

\n\n

How to Avoid?

\n

Choose one method: either an initializer or a constructor. It's better to prefer C# auto-property initializers, as they are more predictable and concise.

\n\n
public class BaseClass\n{\n    public int Value { get; set; } = 10; // Single source of truth\n}
\n\n
\n\n

Mistake #3: Using Readonly Fields Instead of Auto-Properties

\n\n

Some developers, trying to set an initial value, abandon auto-properties and use public fields:

\n\n
public class Config\n{\n    public readonly int MaxRetries = 3; // Mistake: encapsulation violation\n}
\n\n

This is bad practice. Fields violate encapsulation—you won't be able to add logic to the getter/setter without changing the API. Additionally, this creates problems with serialization or when used in WPF/Blazor.

\n\n

The Correct Approach

\n

Use auto-properties with initialization or C# 9 init-only properties:<

Blogs

Book Recommendations