What is the difference between the following expressions for initializing the properties in C# 6:
1. Auto-Property initialized from constructor
public class Context1
{
public Context1()
{
this.Items = new List<string>();
}
public List<string> Items { get; private set; }
}
2: Property initialized from a backing field
public class Context2
{
private readonly List<string> items;
public Context2()
{
this.items = new List<string>();
}
public List<string> Items
{
get
{
return this.items;
}
}
}
3: Auto-Property new syntax in C# 6
public class Context3
{
public List<string> Items { get; } = new List<string>();
}
4: Auto-Property new syntax in C# 6
public class Context4
{
public List<string> Items => new List<string>();
}
What is automatic property? Automatic property in C# is a property that has backing field generated by compiler. It saves developers from writing primitive getters and setters that just return value of backing field or assign to it. Instead of writing property like this: public class Dummy.
C# auto-initialize property is a feature, introduced in 6.0. It allows us to initialize properties without creating a constructor. Now, we can initialize properties along with declaration. In early versions, constructor is required to initialize properties.
Auto-implemented properties declare a private instance backing field, and interfaces may not declare instance fields. Declaring a property in an interface without defining a body declares a property with accessors that must be implemented by each type that implements that interface.
Properties are named members of classes, structures, and interfaces. Member variables or methods in a class or structures are called Fields. Properties are an extension of fields and are accessed using the same syntax.
Listing 3 is C# 6's equivalent of listing 2, where the backing field is provided under the hood.
Listing 4:
public List<string> Items => new List<string>();
is equivalent to:
public List<string> Items { get { return new List<string>(); } }
which as you can imagine returns a new empty list every time you access the property.
The difference between listings 2/3 and 4 is further explored in this Q&A with an example.
Listing 1 is just an auto property with a getter and a private setter. It's not a readonly property in that you can set it anywhere you can access any of the type's private members. A readonly property (that is, a getter-only property) can only be initialized either in a constructor or in the property declaration, much like a readonly field.
Auto-property is a short designation for auto-implemented property, where the developer doesn't need to explicitly declare the backing field and the compiler sets one up behind the scenes.
public class Context1
{
public Context1()
{
this.Items = new List<string>();
}
public List<string> Items { get; private set; }
}
Auto-properties can have different accessibilities for setter and getter by specifying a more restrictive accessibility for the accessor for which the accessibility differs from the property's accessibility.
Other examples are:
public string Prop1 { get; private set; }
public string Prop2 { get; protected set; }
public string Prop3 { get; internal set; }
public string Prop4 { protected internal get; set; }
These accessors with different accessibility can be accessed for anywhere the that accessibility determines, not just from the constructor.
public class Context2 { private readonly List items;
public Context2()
{
this.items = new List<string>();
}
public List<string> Items
{
get { return this.items; }
}
} Prior to C#6, the only way to set the value of a read-only property was to explicitly declare the backing field and set it directly.
Because the field has the readonly
accessor, it can only be set during the construction of the object.
public class Context3
{
public List<string> Items { get; } = new List<string>();
}
Starting with C#6, §2 can be handled by the compiler by have an backing field generated like for read-write auto-properties but, in this case, the backing field is read-only and can only be set during the construction of the object.
public class Context4
{
public List<string> Items => new List<string>();
}
When properties have a value that changes every time it is get, C#6 allows to declare the body of the getter using a lambda-like syntax.
The above code is equivalent to this:
public class Context4
{
public List<string> Items
{
get { return new List<string>(); }
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With