Всем известна функция C#, когда нам не нужно инициализировать каждое свойство объекта отдельно, а просто прописать его в конструкторе.
var obj2 = new Class1("a");
obj2.S = string.Empty;
такой же, как
var obj2 = new Class1("a") {S = string.Empty};
Даже ReSharper так считает:

Но это не просто синтаксический сахар, и это не одно и то же.
Давайте представим пример описания Class1 следующим образом:
public class Class1
{
public string Prop;
public Class1(string s)
{
Prop = s;
}
public string S
{
set => throw new Exception();
}
}
Итак, установка свойства S в строку. Пустое значение вызовет исключение. В этом случае мы можем увидеть разницу между встроенной инициализацией и явной инициализацией.


Когда мы вызываем конструктор и только после его инициализации, объект не является нулевым, а в случае встроенной инициализации мы имеем нулевой объект.
Если мы посмотрим на IL-код, то увидим разницу в реализации:
Явная инициализация:
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
Встроенная инициализация:
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
Здесь главное, где находится инструкция stloc.0 (Поместить значение из стека в локальную переменную 0). В случае встроенной инициализации новый объект Class1 создается и помещается в стек, но не перемещается в локальную переменную из-за исключения в инструкции IL_0012.