CodeGym /Courses /C# SELF /Auto-Properties and init-only Setters

Auto-Properties and init-only Setters

C# SELF
Level 17, Lesson 2
Available

1. Auto-Properties

In C#, properties (property) are kinda like a mix between a field and a method. Basically, it's syntactic sugar that makes working with encapsulation super convenient. You use a property like it's just a regular field, but under the hood, there can be any logic: data validation, changing other fields, calling methods, or even sending an email to your grandma (the last one—not recommended). In the last lecture, we wrote properties by hand. But that gets old fast if you have 100500 simple objects where you just need a "getter" and "setter"—with no special logic.

Enter auto-properties. They'll save you from boilerplate code and let C# handle storing the value for you.

How it used to be: manual properties

When you want to hide a field but give access to it via a property, you usually write it like this:


public class Dog
{
    private string name;

    public string Name
    {
        get { return name; }
        set { name = value; }
    }
}
Manual property with a private field

This kind of code is classic "boilerplate". And most of the time, you don't need to "add" anything to those get/set! Just give access—and that's it.

How you can do it now

In C#, things got way easier: you don't have to write fields by hand anymore—the compiler does it for you. Just write:


public class Dog
{
    public string Name { get; set; }
}
Auto-property

And that's it. You can read and change the Name value, and under the hood, the compiler creates a private field that you can't access directly from outside.

So what's really going on behind the scenes? When you write public string Name { get; set; } in your code, the compiler automatically creates a hidden field like Name__BackingField. Every time you access Name, it inserts the right getter or setter. The field itself isn't visible in your code, but it exists—and you can even find it with reflection (but that's a whole other story).

What's cool about this? First, it's way shorter and you don't have to repeat yourself. Second, your code is cleaner: less visual noise, easier to read and maintain. And finally, it's safer—no one can mess with your fields directly, access is strictly through properties.

2. Auto-Property Syntax

The syntax is super simple:


public class Dog
{
    public string Name { get; set; }
    public int Age { get; set; }
}
Multiple auto-properties

Now our Dog looks way more concise! We can create objects and set values like usual:

Dog myDog = new Dog();
myDog.Name = "Rex";
myDog.Age = 4;

In a nutshell

Way Syntax Value Access
Field
public string Name;
Directly accessible
Manual property
public string Name { get; set; } + private string name;
Access via get/set
Auto-property
public string Name { get; set; }
get/set + hidden field

3. Customizing Access: Read-Only, Write-Only

Read-Only: get-only

If you only need to read a property (like a pet's registration number), you can make it read-only—just specify get, and either don't write set at all, or make it private. You can assign the value only in the constructor or right at the declaration:


public class Dog
{
    public string RegistrationCode { get; }

    public Dog()
    {
        RegistrationCode = "DOG-001"; // Assign value in constructor
    }
}

Now from outside you can only read RegistrationCode, but not change it. Great way to protect important data from accidental changes.

Another option: private set


public string Name { get; private set; }
Private setter—can only be changed inside the class

Then you can only change the property inside the class (like in a method or constructor).

Write-Only: not a great idea

Technically, you can make a set-only property (write-only), but that's super rare and not recommended—imagine an object that acts like a "black hole": you can throw stuff in, but never get it back.

4. init-only setters

A little backstory

Before, if you wanted to make an immutable object (immutable), you had to write get-only properties and set values via the constructor. OK, that's fine—but not always convenient. But recently, C# got a new syntax: init-only properties.

What's the deal with the init setter?

  • Lets you set the property value only when creating the object (i.e. in the constructor or in the object initializer).
  • After the object is created, the property becomes read-only.
  • Perfect for "almost immutable" classes, DTOs, configs, models.

public class Dog
{
    public string Name { get; init; }
    public int Age { get; init; }
}
Properties with init setters

Now you can do this:

Dog dog = new Dog { Name = "Buddy", Age = 2 };
dog.Name = "Rex"; // Error! After creation—read-only

You can also set values in the constructor:

public Dog(string name, int age)
{
    Name = name;
    Age = age;
}

Chart: when can you assign

Where to assign? { get; set; } { get; private set; } { get; init; }
Outside class, after creation ✅ ❌ ❌
In constructor ✅ ✅ ✅
In initializer ✅ ❌ ✅
Inside class ✅ ✅ ❌ (except constructor)

5. Using in Practice

Let's rewrite our Dog class using auto-properties and init-only properties:


public class Dog
{
    // Property, set only during initialization
    public string Name { get; init; }
    public int Age { get; init; }

    // Auto-property for current state
    public bool IsHungry { get; set; }

    // Method, dog's actions
    public void Bark()
    {
        Console.WriteLine($"{Name} says: Woof!");
    }
}

Now we can create Dog like this:

Dog dog = new Dog { Name = "Spot", Age = 3, IsHungry = true };

dog.Bark(); // prints: Spot says: Woof!
dog.IsHungry = false; // you can change this property after creation
dog.Name = "Rex"; // Error! Property is init-only

6. Auto-Properties with Default Values

C# is all about convenience. You can even set a default value for a property right away:


public class Dog
{
    public string Name { get; set; } = "Nameless";
    public int Age { get; set; } = 0;
}
Auto-properties with default values

Or with init:


public class Dog
{
    public string Name { get; init; } = "Puppy";
    public int Age { get; init; } = 0;
}
init-only properties with default values

Now if you don't specify Name when creating, it'll be "Puppy".

7. Auto-Properties with Different Access Levels

You can make a property readable and writable with different access modifiers:


public class Dog
{
    public string Name { get; private set; }
    public int Age { get; private set; }
    
    public Dog(string name, int age)
    {
        Name = name;
        Age = age;
    }
}

In this case, you can only change the name and age inside the Dog class, like in methods or the constructor.

Manual vs Auto-Properties Comparison

Approach Writing Complexity Control in set/get Mutability after creation Use in models
Manual property Long Full Any Where logic is needed
Auto-property Short None Any or private Almost everywhere
init-only auto Short None Only at creation DTOs, configs

8. Common Mistakes with Properties

Mistake #1: trying to assign a value to a get-only property outside the constructor.
If a property is declared with only get, the compiler won't let you change its value anywhere else. You can only assign in the constructor or right at the declaration. Forget that—and you'll get a compile error.

Mistake #2: mixing up a field and a property.
When you replace a regular field with an auto-property, make sure the rest of your code doesn't access the field directly. Field and property are different things, and if you leave old references, the compiler will either throw an error or your program will act weird.

Mistake #3: private set without understanding the consequences.
If a property has a private set, but somewhere else in your code you still try to assign to it—you'll get an error. This happens a lot by accident, especially when copying someone else's code. Always check if set is available where you want to use it.

2
Task
C# SELF, level 17, lesson 2
Locked
Using init-only properties
Using init-only properties
2
Task
C# SELF, level 17, lesson 2
Locked
Auto-properties with Initial Values
Auto-properties with Initial Values
Comments
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION