Przejdź do treści stopki
Iron Academy Logo
Naucz się C#
Naucz się C#

Inne Kategorie

Nowe słowo kluczowe field w C# 14

Tim Corey
10m 35s

Auto-właściwości w C# są zwięzłe, ale jeśli potrzebujesz logiki walidacji lub transformacji w setterze, musiałeś całkowicie z nich zrezygnować i napisać pełną właściwość z ręcznie obsługiwanym polem pomocniczym. Przejście z jednej linii na siedem jest znaczącym obciążeniem dla dodania jednej klauzuli zabezpieczającej. C# 14 wprowadza slowo kluczowe field, aby zamknac te luke, pozwalajac ci dostosowac getter lub setter, podczas gdy kompilator nadal zarzadza polem wspierajacym dla ciebie.

W swoim wideo "The New field Keyword in C# 14" Tim Corey demonstruje problem, który ta funkcja rozwiązuje, przeprowadza przez praktyczne przykłady walidacji settera i opisuje konflikt nazewnictwa, o którym warto wiedzieć przed aktualizacją. Przejdziemy szczegolowo kazdy krok, aby mozna bylo zaczac uzywac field we wlasnych wlasciwosciach z pewnoscia.

Konfiguracja: Prosty model osoby

[0:12 - 1:07] Tim zaczyna od aplikacji konsolowej dzialajacej na .NET 10 i Visual Studio 2026. Prezentacja koncentruje sie na klasie Person z kilkoma wlasciwosciami:

public required string FirstName { get; set; }
public required string LastName { get; set; }
public int Age { get; set; }
public required string FirstName { get; set; }
public required string LastName { get; set; }
public int Age { get; set; }

Istnieje rowniez wlasciwosc Demo wspierana przez prywatne pole, ktora staje sie istotna, gdy pojawia sie konflikt nazw. W Program.cs, Tim tworzy instancje z FirstName = "Tim" i LastName = "Corey", a nastepnie drukuje nazwisko, wiek i wartosc demo. Wszystko wyświetla się zgodnie z oczekiwaniami: "Corey", 0 (domyślny integer) i "test".

Problem: Auto-właściwości akceptują błędne dane

[1:23 - 2:49] Problem pojawia sie, gdy Tim przypisuje null do LastName po konstrukcji:

p.LastName = null;
p.LastName = null;

Mimo ze LastName jest oznaczone required i wpisane jako lancuch nienullowalny, przypisanie jest kompilowane. Modyfikator required wymusza jedynie, by wartosc byla zapewniona podczas inicjalizacji obiektu; nie zapobiega to jednak ustawieniu wlasciwosci na null pozniej. Wynikiem jest pusta nazwa podczas wykonywania bez rzucania błędu.

To prawdziwa luka w integralności danych. System typu ostrzega cię za pomocą nullable reference squiggle, ale to tylko podpowiedź w czasie kompilacji, nie ochrona w czasie wykonywania. Jesli twoja aplikacja zalezy od LastName zawsze zawierajacej prawidlowy lancuch, auto-wlasciwosci same nie moga tego kontraktu wymusic.

Stare rozwiązanie: Pełne właściwości z ręcznymi polami pomocniczymi

[2:58 - 4:19] Przed C# 14 standardowym rozwiązaniem było przekształcenie auto-właściwości w pełną właściwość z explicite pole pomocnicze:

private string _lastName;
public required string LastName
{
    get => _lastName;
    set => _lastName = value ?? throw new ArgumentNullException(nameof(LastName));
}
private string _lastName;
public required string LastName
{
    get => _lastName;
    set => _lastName = value ?? throw new ArgumentNullException(nameof(LastName));
}

Tim uruchamia to i potwierdza, że wyjątek uruchamia się poprawnie: "Wartość nie może być null. Nazwa parametru: LastName." Podejście działa, ale wymaga zadeklarowania prywatnego pola, połączenia zarówno gettera, jak i settera oraz powtórzenia nazwy właściwości na kilku liniach. Dla jednej reguły walidacji to dużo ceremonii.

Getter w tym przypadku nie robi nic szczególnego; zwraca niezmienione pole. Mimo to musisz je napisać explicite, ponieważ składnia wymaga obu połówek po opuszczeniu auto-właściwości. Tim ujęcia tę rozwlekłość jako motywację dla nowej funkcji.

Rozwiązanie w C# 14: Słowo kluczowe field

[4:23 - 5:47] C# 14 wprowadza środkową drogę. Zamiast deklarowac prywatne pole wspierajace samodzielnie, uzywasz kontekstowego slowa kluczowego field wewnatrz gettera lub settera, by bezposrednio odwolac sie do generowanego przez kompilator pola wspierajacego:

public required string LastName
{
    get;
    set => field = value ?? throw new ArgumentNullException(nameof(LastName));
}
public required string LastName
{
    get;
    set => field = value ?? throw new ArgumentNullException(nameof(LastName));
}

Getter pozostaje auto-zaimplementowanym get; bez potrzeby posiadania ciala. Setter uzywa field do przypisania nadchodzacego value po walidacji. Kompilator tworzy i zarządza polem pomocniczym w tle, tak jak to robi ze standardową auto-właściwością.

Uruchomienie prezentacji daje ten sam ArgumentNullException przy przypisaniu null. Zachowanie jest identyczne z wersją ręcznie wspieraną, skompresowaną z siedmiu linijek na zwięzły blok, który dostosowuje tylko to, co wymaga dostosowania. Zachowujesz auto-właściwość gettera, dodajesz logikę tylko do settera i pomijasz ręczne deklarowanie pola całkowicie.

Daje to użyteczną środkową opcję między czystą auto-właściwością (jedna linia, brak walidacji) a pełną właściwością (siedem lub więcej linii, pełna kontrola). Kiedy twoja logika dotyka tylko settera, nie płacisz syntaktycznego kosztu przepisywania także gettera.

Walidacja wieku za pomocą blokady Settera

[6:16 - 7:39] Aby pokazac, ze field nie jest ograniczone do sprawdzania null, Tim dodaje walidacje zakresu do wlasciwosci Age:

public int Age
{
    get;
    set
    {
        if (value > 0 && value < 120)
            field = value;
    }
}
public int Age
{
    get;
    set
    {
        if (value > 0 && value < 120)
            field = value;
    }
}

Tutaj setter cicho ignoruje wartości poza rozsądnym zakresem. Przypisanie -5 zostawia Age na domyslnym poziomie zerowym, poniewaz warunek jest niepelniony i field nigdy nie jest zapisane. Tim zauwaza, ze mozna byloby wyrzucic wyjatek zamiast tego, ale podejscie bezglosne pokazuje, ze cialo settera moze zawierac dowolna logike, jaka potrzebujesz, opierajac sie nadal na field do przechowywania.

Wzór ma szerokie zastosowanie: przymierzanie zakresów numerycznych, przycinanie spacji z ciągów, normalizowanie wielkości liter lub dowolna transformacja, którą chcesz zastosować za każdym razem, gdy właściwość jest ustawiana.

Konflikty nazwowości z istniejącymi zmiennymi field

[7:39 - 9:43] Tim wprowadza celowy przypadek brzegowy. Klasa demo ma prywatnego czlonka doslownie nazwanego field:

private string field = "test";
private string field = "test";

Po aktywacji C# 14, kompilator traktuje field wewnatrz dostepnika wlasciwosci jako slowo kluczowe, a nie zmienna. To znaczy, ze wlasciwosc odnosi sie do field, dyskretnie odczytujac z ukrytego magazynu za wlasciwoscia (ktory jest pusty), zamiast czlonka lancucha zawierajacego "test". Wyjście zmienia się na puste bez błędu kompilacji, tylko z ostrzeżeniem.

Istnieja dwa obejscia. Dodanie przedrostka this.field mowi kompilatorowi, ze masz na mysli czlonka na poziomie klasy, a nie slowo kluczowe. Alternatywnie @field ucieczka dziala w ten sam sposob:

// Both refer to the instance variable, not the keyword
string demo => this.field;
string demo => @field;
// Both refer to the instance variable, not the keyword
string demo => this.field;
string demo => @field;

Zdecydowanie zalecenie Tima to zmiana nazw wszystkich zmiennych nazywanych field podczas aktualizacji do C# 14. Szybkie "Rename All" w IDE usuwa niejednoznacznosc na stale. Konflikt występuje tylko wewnątrz akcesorów właściwości; Konstruktory i metody rozwiazuja field do nazwy zmiennej, jak oczekiwano, poniewaz konteksty te nie maja implicitnego magazynu wspierajacego.

Zakończenie: Mniej szablonu, ta sama kontrola

[10:04 - 10:28] Slowo kluczowe field wypelnia praktyczna luke w codziennym kodzie C#. Właściwości potrzebujące jednej klauzuli zabezpieczającej lub transformacji nie wymagają już pełnego przepisania z ręcznymi polami pomocniczymi. Dostosowujesz tylko ten akcesor, który wymaga logiki, a drugi pozostaje jako standardowa auto-implementacja.

Wnioski

[10:28 - 10:35] Podsumowujac: slowo kluczowe field w C# 14 daje ci bezposredni dostep do implicitnego magazynu wspierajacego wewnatrz dowolnego dostepnika wlasciwosci. Używaj tego do dodania walidacji settera, transformacji gettera lub obu, bez porzucania składni auto-właściwości dla części, które nie wymagają dostosowania.

Przed aktualizacja, przeszukaj swoja baze kodu pod katem dowolnych zmiennych nazwanych field i zmien ich nazwy. Ta jedna środa zapobiega jedynemu prawdziwemu "gotcha", którą ta funkcja wprowadza. Poza tym jest to czyste zmniejszenie ilości szablonu, które naturalnie wpisuje się w to, jak większość deweloperów już strukturalizuje swoje modele.

Przyklad Tip: Jesli potrzebujesz jedynie walidowac setter, pozostaw getter jako zwykla get; bez ciala. Kompilator traktuje to jako auto-zrealizowany getter właściwości, a ty unikasz pisania instrukcji return, który nie dodaje niczego.

Obejrzyj pełne wideo na jego kanale YouTube i zdobądź więcej informacji na temat funkcji języka C#.

Hero Worlddot related to Nowe słowo kluczowe field w C# 14
Hero Affiliate related to Nowe słowo kluczowe field w C# 14

Zarabiaj więcej, dzieląc się tym, co kochasz

Tworzysz treści dla deweloperów pracujących z .NET, C#, Java, Python, czy Node.js? Zamień swoją wiedzę specjalistyczną na dodatkowy dochód!

Zespol wsparcia Iron

Jestesmy online 24 godziny, 5 dni w tygodniu.
Czat
Email
Zadzwon do mnie