Auto properties – jak działają?
Automatyczne property są z nami od C# 3. Dzięki nim udało się zaoszczędzić ogromną ilość czasu programistów a co za tym idzie ograniczyć ilość produkowanych błędów. Mimo tego, że codziennie są stosowane przez wszystkich programistów C# co jakiś czas spotykam się z pytaniem jak one działają i skąd się wzięły. W tym artykule postaram się odpowiedzieć na oba te pytania.
Rys historyczny
Jak wszystkim wiadomo C# od samego początku miał być bezpośrednią konkurencją dla Javy. C# wyszedł z propozycją koncepcji property ale najpierw przyjrzyjmy się jak w Javie wyglądał by kod, który pobiera i ustawia wiek osoby:
// Kod Javy przetłumaczony na C#
public class Person
{
private int _age;
public int GetPersonAge()
{
return _age;
}
public void SetPersonAge(int value)
{
_age = value;
}
}
Sporo kodu. 15 Linijek tylko po to, żeby udostępnić możliwość ustawiania jednego pola (Java do tej pory nie ma koncepcji property i trzeba pisać kod jak wyżej).
C# 1
W 2002 roku kiedy C# ujrzał światło dzienne już posiadał koncept property, który wygląda znajomo ale jednak jeszcze mu daleko do postaci którą teraz znamy:
public class Person
{
private int _age;
public int Age
{
get { return _age; }
set { value = _age; }
}
}
// nie można było używać takiej składni przy tworzeniu nowego obiektu:
var person = new Person()
{
Age = 10
};
// zamiast tego musieliśmy to robić tak:
var person = new Person();
person.Age = 10;
Spore udogodnienie względem poprzedniego kodu. Od początku wszyscy pisali kod w sposób przedstawiony wyżej. Jak się z czasem okazało, większość property nie miało żadnej logiki ani walidacji.
C# 3
Niestety na usprawnienie tego mechanizmu przyszło nam czekać 5 lat. Dopiero z nadejściem trzeciej wersji C# w 2007 roku, Microsoft zaimplementował automatyczne property jakie znamy teraz:
public class Person
{
public int Age { get; set; }
}
// można już używać takiej składni:
var person = new Person()
{
Age = 10
};
powyższy kod jest kompilowany do:
public class Person
{
[CompilerGenerated]
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private int <Age>k__BackingField;
public int Age
{
[CompilerGenerated]
get
{
return <Age>k__BackingField;
}
[CompilerGenerated]
set
{
<Age>k__BackingField = value;
}
}
}
Wygląda znajomo? Tak, kod auto property jest kompilowany do get/set znanego z c# 1.
C# 6
W szóstej wersji C# nie było dużych zmian. Dodano tylko możliwość przypisania domyślnej wartości do property:
public class Person
{
public int Age { get; set; } = 10;
}
Modyfikatory dostępu
Przykładowe modyfikatory dostępu:
// dostępny publicznie ale ustawić można tylko wewnątrz klasy
public int Age { get; private set; }
// dostępny publicznie ale ustawić można wewnątrz tego samego namespace
public int Age { get; internal set; }
// dostępny publicznie ale ustawić wartość można tylko przy tworzeniu obietku.
public int Age { get; init; }