Wednesday, September 15, 2021

C# 9.0 - Introduction To Init-Only Property

 In this article, I am going to explain the Init-only setter property which has been introduced in C# 9.0.

 
Each C# release has its own features. In C# 9.0, many new wonderful features have been added and here we are going to discuss important feature Init-only setter property.
Before we start, we should have a basic understanding of immutable and mutable in c#.
 
What’s the meaning of Mutable and Immutable in English?
 
Answers are:
  • Mutable – Can change
  • Immutable – Cannot Change
In simple words, we can say, immutable means an object cannot be changed once it is created. If you want to change, you have to create new object/ assign new memory. An example of the immutable type is a string in C#.
 

What is Init-only setter property?

 
Before we start with Init-only property, we have to understand the traditional way of working (properties).
 
Let’s start with an example,
 
Suppose, we have Member class which has 3 properties, 
  1. ID - Member unique ID
  2. Name - Member Name
  3. Address - Member Address
    public class Member
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Address { get; set; }
    }
    C#
Now create an object of Member class and assign some values,
using System;

namespace C_9._0
{
    class Program
    {
        static void Main(string[] args)
        {
            Member memberObj = new Member();
            memberObj.Id= 1;
            memberObj.Name="Kirtesh Shah";
            memberObj.Address="Vadodara";

            Console.WriteLine("****************START - Member Details***********");

            Console.WriteLine("ID : -" + memberObj.Id);
            Console.WriteLine("Name :- " + memberObj.Name);
            Console.WriteLine("Address:- " + memberObj.Address);
            Console.ReadLine();

            Console.WriteLine("****************END - Member Details***********");
        }
    }
}
C#

All looks good, right? But what happens if someone changed Member  ID? ID is unique and it should not be editable, which means it should be immutable, not mutable. That's the problem with the traditional way, properties are mutable.

If we want to make properties immutable in the traditional way, we have to pass values in the constructor like the below code,

public class Member
{
    public Member(int memberId)
    {
        Id = memberId;
    }
    public int Id { get; }
    public string Name { get; set; }
    public string Address { get; set; }
}
C#
ID property is immutable now.

Let's see the below code:
using System;
namespace C_9._0 {
    class Program {
        static void Main(string[] args) {
            Member memberObj = new Member(1);
            memberObj.Name = "Kirtesh Shah";
            memberObj.Address = "Vadodara";
            Console.WriteLine("****************START - Member Details***********");
            Console.WriteLine("ID : " + memberObj.Id);
            Console.WriteLine("Name : " + memberObj.Name);
            Console.WriteLine("Address: " + memberObj.Address);
            Console.ReadLine();
            Console.WriteLine("****************END - Member Details***********");
        }
    }
}
C#

The output of above code would be,

C# 9.0 - Introduction To Init-Only Property
 
Now ID property is Immutable and cannot be changed once an object is created. To make the mutable property into immutable, we have to create a constructor.
 
In C# 9.0, we can achieve the same thing using Init-only property.
public class Member {
    public int Id {
        get;
        init;
    } // set is replaced with init
    public string Name {
        get;
        set;
    }
    public string Address {
        get;
        set;
    }
}

using System;
namespace C_9._0 {
    class Program {
        static void Main(string[] args) {
            Member memberObj = new Member {
                Id = 1
            };
            memberObj.Name = "Kirtesh Shah";
            memberObj.Address = "Vadodara";
            Console.WriteLine("****************START - Member Details***********");
            Console.WriteLine("ID : " + memberObj.Id);
            Console.WriteLine("Name : " + memberObj.Name);
            Console.WriteLine("Address: " + memberObj.Address);
            Console.ReadLine();
            Console.WriteLine("****************END - Member Details***********");
        }
    }
}
C#

We got the same output as in the previous code 

    C# 9.0 - Introduction To Init-Only Property
     
    It is the power of Init-only property. What will we do, if we want to do some validation like ID should not be null or string? Init-only property has the capability to set a read-only property to implement validations.
     
    Suppose we have a Member class like below,
    public class Member
    {
        public int Id { get; init; }
        public string Name { get; init; }
        public string Address { get; init; }
    }
    C#

    Now we will try to create a Member class object like below,

    using System;
    
    namespace C_9._0
    {
        class Program
        {
            static void Main(string[] args)
            {
                Member memberObj = new Member
                {
                      Id =1
                };
                Console.WriteLine("****************START - Member Details***********");
    
                Console.WriteLine("ID : " + memberObj.Id);
                Console.WriteLine("Name : " + memberObj.Name);
                Console.WriteLine("Address: " + memberObj.Address);
                Console.ReadLine();
    
                Console.WriteLine("****************END - Member Details***********");
            }
        }
    }
    C#

    Init-only properties can or cannot be set as per your requirement. As you notice in the above code, only ID property is set and name and address properties are not set. Please note that if any property is not set at the time of object creation that property cannot be set.

    No comments:

    Post a Comment

    How to register multiple implementations of the same interface in Asp.Net Core?

     Problem: I have services that are derived from the same interface. public interface IService { } public class ServiceA : IService { ...