Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is difference between Init-Only and ReadOnly in C# 9?

Tags:

c#

c#-9.0

I am going through C# 9 new features which will be released soon. Init-Only properties are being introduced with it.

The one big limitation today is that the properties have to be mutable for object initializers to work: They function by first calling the object’s constructor (the default, parameterless one in this case) and then assigning to the property setters.

Init-only properties fix that! They introduce an init accessor that is a variant of the set accessor which can only be called during object initialization:

public class Person
{
    public string FirstName { get; init; }
    public string LastName { get; init; }
}

With this declaration, the client code above is still legal, but any subsequent assignment to the FirstName and LastName properties is an error. What does this line mean? If ReadOnly also does the same thing then what is use of Init-Only property.

like image 886
vivek nuna Avatar asked Dec 02 '22 09:12

vivek nuna


2 Answers

As stated in the new C# 9 features post,

The one big limitation today is that the properties have to be mutable for object initializers to work: They function by first calling the object’s constructor (the default, parameterless one in this case) and then assigning to the property setters.

However, value types with readonly modifiers are immutable as stated in readonly documentation.

Therefore, it is not possible to use readonly properties with object initializers.

However, with Init-only properties you can use object initializers.

like image 60
emre nevayeshirazi Avatar answered Jan 01 '23 12:01

emre nevayeshirazi


The purpose of Init-only properties is to allow assignation only in the object initializer or the constructor for your class.

If we consider your Person class, assigning to FirstName or LastName is allowed in the constructor or in the object initializer but you can't assign to FirstName or LastName in other places :

public class Person
{
    public string FirstName { get; init; }
    public string LastName { get; init; }

    // this is a constructor
    public Person()
    {
        this.FirstName = "first name"; // works
        this.LastName = "last name"; // works
    }
}

//this is a random method
public SomeMethod()
{
    Person myPerson = new Person
    {
        FirstName = "first name", // works
        LastName = "last name" // works
    };

    myPerson.FirstName = "change the first name"; // Error (CS8852)
    myPerson.LastName = "change the last name"; // Error (CS8852)
}
like image 43
nalka Avatar answered Jan 01 '23 12:01

nalka