Why inline initialization is not just syntax sugar in C#

Everybody knows C# feature where we don’t have to initialize each object property separately, but just write it inline with constructor.

var obj2 = new Class1("a");
obj2.S = string.Empty;

is same as

var obj2 = new Class1("a") {S = string.Empty};

Even ReSharper thinks so:

But it is not just syntax sugar and it is not the same.

Lets imagine the example of Class1 description like that:

public class Class1
{
public string Prop;
      public Class1(string s)
      {
           Prop = s;
      }
      public string S
      {
          set => throw new Exception();
      }
}

So, setting S property to string.Empty value would cause an exception. In this case we can see the difference between inline initialization and explicit initialization.

When we call constructor and only after it initialization, object is not null and in the case of inline initialization we have null object.

If we look at IL code we’ll see the difference in the implementation:

Explicit initialization:

IL_0002:  ldstr      "a"
IL_0007: newobj instance void ConsoleApp2.Class1::.ctor(string)
IL_000c: stloc.0
IL_000d: ldloc.0
IL_000e: ldsfld string [System.Runtime]System.String::Empty

Inline initialization:

IL_0002:  ldstr      "a"
IL_0007: newobj instance void ConsoleApp2.Class1::.ctor(string)
IL_000c: dup
IL_000d: ldsfld string [System.Runtime]System.String::Empty
IL_0012: callvirt instance void ConsoleApp2.Class1::set_S(string)
IL_0017: nop
IL_0018: stloc.0

The main thing here is where stloc.0 instruction (Pop a value from stack into local variable 0) is located. In the case of inline initialization new Class1 object is created and placed to the stack, but it is not moved to local variable because of exception in IL_0012 instruction.