Why can't I initialize an Init property directly/without the use of an Object Initializer?

Shervan360 1,661 Reputation points
2024-10-08T06:23:29.4333333+00:00

Hello,

We can initialize the Init property with Object Initializer. In fact, an Object initializer is equivalent to the variable/property initializer.

If the compiler translates an Object initializer to a conventional variable initialization, Why can't I initialize an Init property directly/without the use of an Object Initializer?

namespace ConsoleApp1
{
     internal class Program
     {
          static void Main(string[] args)
          {
               My m = new()
               {
                    MyProperty = 10
               };
               My m1 = new();
               // m1.MyProperty = 10; //ERROR
               Console.WriteLine(m1.MyProperty);
          }
     }
     class My
     {
          public int MyProperty { get; init; }
          public My()
          {
          }
     }
}

Screenshot 2024-10-08 093701

.NET
.NET
Microsoft Technologies based on the .NET software framework.
4,103 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
11,409 questions
{count} votes

Accepted answer
  1. gekka 11,691 Reputation points MVP
    2024-10-09T03:42:58.31+00:00

    Why are you decompiling with most oldest version intentionally?

    20241009_A

    Object-Initializers cannot be expressed in C#1 because of the description method introduced in C# version 3.

    It stands to reason that if you decompile with older version, it will not be able to interpret the new functionality.
    Compilers that support C#9 can now add custom modifiers to property setters to enable new access restrictions.

    //public int MyProperty { get; set; }
    .method public hidebysig specialname instance void set_MyProperty (int32 'value') cil managed 
    
    //public int MyProperty { get; internal set; }
    .method assembly hidebysig specialname instance void set_MyProperty (int32 'value') cil managed 
    
    //public int MyProperty { get; init; }
    .method public hidebysig specialname instance void modreq([System.Runtime]System.Runtime.CompilerServices.IsExternalInit) set_MyProperty (int32 'value') cil managed 
    
    //public int MyProperty { get; internal init; }
    .method assembly hidebysig specialname instance void modreq([System.Runtime]System.Runtime.CompilerServices.IsExternalInit) set_MyProperty (int32 'value') cil managed 
    

    modreq in IL is Custom modifier for member access like as public or private.

    If you use compiler that is supported only older versions, it will not be able to resolve this modifier and therefore will not compile.
    Similarly, ILSpy's C# 1.0 decompiler is not able to decompile this modreq as an init.

    For a more detailed understanding you need to study the IL language.

    0 comments No comments

1 additional answer

Sort by: Most helpful
  1. Bruce (SqlWork.com) 74,531 Reputation points
    2024-10-08T15:11:00.2833333+00:00

    The init operator is a compiler feature (syntax sugar), not a .net runtime feature. The compiler uses the property to set the value, but disallows code from doing it. The il decompiler is not smart enough to produce compilable code.

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.