C# init equals private set?

Question:

I was reading about the new implementations in C# 9 and came across init , init-only-setters :

Starting with C# 9.0, you can create init accessors instead of set accessors for properties and indexers.

In free translation:

Starting with C# 9.0, you can create init "advisors" instead of defining set for properties and indexers.

See the code example below:

public class Pessoa
{ 
  public string Nome { get; init; } 
  public string Idade { get; set; } 
} 

You can instantiate the class like this, "in the constructor":

var pessoa = new Pessoa
{
    Nome = "Fulano",
    Idade = 20
};

The Idade property can be changed after the instance, but the Nome property cannot be changed:

pessoa.Nome = "Outro";  // isso dá erro

Isn't that the same as declaring the Nome property like this?

public string Nome { get; private set; }

If so, is there any advantage to using init instead of private set ?

Answer:

The behaviors of the two access modifiers are quite different. The fact that it is not possible to change the property value outside the class is the only similarity.

In fact, init-only properties are more similar to getter-only properties. In this case the difference is that init-only properties can be initialized when constructing an object ( using object initialization syntax ) and getter-only properties can only be initialized in a constructor itself.

Back to the differences between init-only and private setter . Let's use the class below as a basis.

public class Pessoa
{    
    public string Nome { get; init; }
    public string Sobrenome { get; private set; }
}

The property with the init modifier cannot have its value changed even within the Pessoa class. In this case the compiler issues error CS0272 .

public class Pessoa
{ 
    // ...
     
    void MudarNome(string novoNome) 
    {
        // Isso é inválido! 
        Nome = novoNome;
    }

    void MudarSobrenome(string novoSobrenome)
    {
        // Isso é válido!
        Sobrenome = novoSobrenome;    
    }
}

Also, as mentioned earlier, the init-only property can be initialized when creating an object. The property with private setter cannot have its value set, if you try to do this the compiler will issue error CS8852 (I couldn't find the link to this error in the documentation ).

var objeto = new Pessoa
{
    Nome = "Matheus",   // Isso é válido
    Sobrenome = "Silva" // Isso não é válido
}; 
Scroll to Top