Both the automatic properties available since C # 2 and the initialization of them since version 6 are just syntactic sugars. You can even create the property more "manual" and initialize it in a constructor.
Of course if you go deeper the property itself is just a couple of methods with specific characteristics, but let's stay in this first layer of abstraction.
When you write
class Exemplo {
public int valor { get; set; } = 1;
}
In the background it's the same as
internal class Exemplo {
private int valor;
public int Valor {
get { return valor; }
set { valor = value; }
}
public Exemplo() {
valor = 1;
}
}
In fact the compiler generates a code next to it:
.class private auto ansi beforefieldinit AutoPropertyInitializer.Exemplo
extends [mscorlib]System.Object {
.field private int32 '<Property>k__Valor'
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
.method public hidebysig specialname instance int32
get_Valor() cil managed {
//corpo aqui
}
.method public hidebysig specialname instance void
set_Valor(int32 'value') cil managed {
//corpo aqui
}
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed {
// Code size 18 (0x12)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldc.i4 0x1
IL_0006: stfld int32 AutoPropertyInitializer.Exemplo::'<Property>k__Valor'
IL_000b: ldarg.0
IL_000c: call instance void [mscorlib]System.Object::.ctor()
IL_0011: ret
}
.property instance int32 Valor() {
.get instance int32 AutoPropertyInitializer.Exemplo::get_Valor()
.set instance void AutoPropertyInitializer.Exemplo::set_Valor(int32)
}
}