The next new feature of the C# 6.0 is auto-property initializers and get-only auto property. The main problem that they suppose to solve is immutable type declaration. Before C# 6.0, if you want to create immutable type with properties, you have no possibility to use auto property:

public string Property { get ; set ; }

So, you were forced to use regular get-only (read-only) property with read-only backing field:

private readonly string prop ; public string Prop { get { return prop ; } } public Ctor ( ) { prop = "value" ; }

Now, with C# 6.0, you can write:

public string Prop { get ; } = "value" ;

Of course, you can use property initialization not only with read-only auto property. Regular one is also working well:

public string Prop { get ; set ; } = "value" ;

The same as static one:

public static string Prop { get ; set ; } = "value" ;

You can even use expressions to initialize property:

public string Prop { get ; set ; } = InitializeProperty ( ) ; public static string InitializeProperty ( ) { return "value" ; }

Internal Implementation

As you may know, C# compiler generates a backing field for auto property. If the property is read-only (get-only) it generates a read-only backing field. In this part nothing changed.

But if you are using auto-property initializer it will also add backing field initialization in the type's constructor. In case of Read\Write auto property:

public int Property { get ; set ; } = 777 ;

"Inner" code will look like this:

internal class TestClass { private int backingField ; public int Property { get { return backingField ; } set { backingField = value ; } } public TestClass ( ) { backingField = 777 ; } }

To check that just look at generated IL:

. class private auto ansi beforefieldinit AutoPropertyInitializer . TestClass extends [ mscorlib ] System . Object { . field private int32 '<Property>k__BackingField' . custom instance void [ mscorlib ] System . Runtime . CompilerServices . CompilerGeneratedAttribute :: . ctor ( ) = ( 01 00 00 00 ) . method public hidebysig specialname instance int32 get_Property ( ) cil managed { } . method public hidebysig specialname instance void set_Property ( int32 'value' ) cil managed { } . method public hidebysig specialname rtspecialname instance void . ctor ( ) cil managed { . maxstack 8 IL_0000 : ldarg . 0 IL_0001 : ldc . i4 0x309 IL_0006 : stfld int32 AutoPropertyInitializer . TestClass :: '<Property>k__BackingField' IL_000b : ldarg . 0 IL_000c : call instance void [ mscorlib ] System . Object :: . ctor ( ) IL_0011 : ret } . property instance int32 Property ( ) { . get instance int32 AutoPropertyInitializer . TestClass :: get_Property ( ) . set instance void AutoPropertyInitializer . TestClass :: set_Property ( int32 ) } }

As you can see, backing field is initializing in the constructor (line IL_0001 and IL_0006).

With get-only auto property you will get almost the same result. Only one difference, backing field will be read-only and you will have no setter (set_Property method):

. field private initonly string '<Property>k__BackingField'

For static auto-property, initialization happens in the static constructor.