Zrozumienie właściwości w C#
C# 11, wprowadzony wraz z .NET 7, przyniósł ekscytujący dodatek do własności: słowo kluczowe required. W tym artykułe zbadamy właściwości C# z przykładami z zwięzłego samouczka wideo Tima Coreya pt. ".NET 7 Update: Required Properties in 10 Minutes or Less". Rozłożymy wszystko od podstaw właściwości po nowe słowo kluczowe required i sposób, w jaki pomaga ono wymusić zasady inicjalizacji.
Właściwości C
W C# właściwości pozwalają kapsułkować pola i zarządzać dostępem do członków danych klasy obiektu. Są powszechnie używane do zapewniania integralności danych przy jednoczesnym umożliwieniu dostępu zewnętrznego. Prywatne pole można kapsułkować za pomocą właściwości, oferując kontrolę nad sposobem dostępu do danych lub ich modyfikacji. Publiczne właściwości typu string często korzystają ze specjalnych metod zwanych akcesorami (get i set) do efektywnego manipulowania członkami klasy. Statyczna właściwość w C# może być dostępna bez tworzenia instancji klasy, oferując unikalny sposób zarządzania wartościami właściwości.
Oto jak Tim ustawia prosty przykład właściwości do demonstracji.
Tworzenie aplikacji konsolowej
Najpierw Tim zaczyna od podstawowej aplikacji konsolowej .NET 7 przy użyciu C# 11. Ta wersja wprowadza słowo kluczowe required, które nie jest dostępne w poprzednich wersjach .NET.
Definiowanie prostego modelu
Tim tworzy klase PersonModel z wlasciwosciami dla FirstName i LastName:
public class PersonModel
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
public class PersonModel
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
Te wlasciwosci pozwalaja PersonModel na przechowywanie imienia i nazwiska. Jednak bez dodatkowej konfiguracji, FirstName i LastName moga potencjalnie pozostac niezainicjalizowane, co prowadzi do wartosci null.
Używanie konstruktorów do zapewnienia inicjalizacji
Powszechnym sposobem zapewnienia, że właściwości są zawsze inicjowane, jest użycie konstruktóra. W przykladzie Tima dodaje on konstruktor do klasy bazowej PersonModel, ktory wymaga zarowno FirstName, jak i LastName:
public PersonModel(string firstName, string lastName)
{
FirstName = firstName;
LastName = lastName;
}
public PersonModel(string firstName, string lastName)
{
FirstName = firstName;
LastName = lastName;
}
Takie podejscie wymusza, ze za kazdym razem, gdy obiekt PersonModel jest tworzony, nalezy podac zarowno FirstName, jak i LastName. Gdybysmy chcieli utworzyc PersonModel bez okreslenia tych wartosci, kompilator zglosilby blad.
Kontekst dla nullables
Poczawszy od .NET 6 i C# 10, C# wprowadzil typy referencyjne przypisujace NULL. Oznacza to, ze wlasciwosci musza byc albo zainicjalizowane, albo jawnie oznaczone jako nullable za pomoca ?. Na przyklad, jesli FirstName i LastName moga byc null, zdefiniowalibysmy je w nastepujacy sposob:
public string? FirstName { get; set; }
public string? LastName { get; set; }
public string? FirstName { get; set; }
public string? LastName { get; set; }
W przykladzie Tima zakladamy jednak, ze FirstName i LastName zawsze powinny byc nie-null. Początkowo, obsługę nullów zapewniała ostrożna inicjalizacja lub adnotacje nullables, ale wraz z C# 11, mamy bardziej solidne opcje.
Wprowadzenie słowa kluczowego required
Chociaz konstruktory moga wymuszac inicjalizacje, C# 11 wprowadza slowo kluczowe required, ktore ulatwia upewnienie sie, ze okreslone wlasciwosci zostaly ustawione. Dzieki required mozna oznaczyc poszczegolne wlasciwosci jako wymagane, co oznacza, ze musza zostac przypisane wartosci podczas inicjalizacji obiektu.
Konfiguracja właściwości required
Aby uczynic FirstName i LastName wymaganymi wlasciwosciami, Tim o 4:15 modyfikuje klase PersonModel w nastepujacy sposob:
public class PersonModel
{
public required string FirstName { get; set; }
public required string LastName { get; set; }
}
public class PersonModel
{
public required string FirstName { get; set; }
public required string LastName { get; set; }
}
Oznaczajac te wlasciwosci za pomoca required, kompilator bedzie teraz wymuszac ich ustawienie albo przez inicjator obiektu, albo przez konstruktor. Jest to przydatne, ponieważ pozwala na wymaganie określonych właściwości bez konieczności tworzenia konstruktóra.
Przykładowe zastosowanie z wymaganymi właściwościami
Teraz mozemy tworzyc i inicjalizowac PersonModel w nastepujacy sposob:
PersonModel person = new() { FirstName = "Tim", LastName = "Corey" };
PersonModel person = new() { FirstName = "Tim", LastName = "Corey" };
Jesli pominiemy FirstName lub LastName, kompilator zglosi blad, zmuszajac nas do zainicjalizowania tych wymaganych wlasciwosci.
Użycie required z konstruktórami
Tim przedstawia przypadek, w ktorym uzywane sa zarowno wlasciwosci required, jak i konstruktory. W sytuacjach, gdy mamy do czynienia z konstruktorem, który ustawia wymagane właściwości, język C# musi zapewnić, że właściwości te są nadal inicjowane w momencie wywołania konstruktóra.
W takich przypadkach mozna uzyc atrybutu SetsRequiredMembers, aby wskazac, ze konstruktor spelnia wymagane warunki. Oto, jak Tim to stosuje:
[SetsRequiredMembers]
public PersonModel()
{
FirstName = "Test";
LastName = "Test";
}
[SetsRequiredMembers]
public PersonModel(string firstName, string lastName)
{
FirstName = firstName;
LastName = lastName;
}
[SetsRequiredMembers]
public PersonModel()
{
FirstName = "Test";
LastName = "Test";
}
[SetsRequiredMembers]
public PersonModel(string firstName, string lastName)
{
FirstName = firstName;
LastName = lastName;
}
Dodanie SetsRequiredMembers informuje kompilator, ze te wlasciwosci beda ustawione w konstruktorze, unikajac bledow inicjalizacji. Ta funkcja pomaga zapobiegać przypadkowym pominięciom, zapewniając jednocześnie elastyczność w inicjalizacji właściwości.
Dłączego wymagane właściwości są przydatne
Tim wyjasnia, ze nowe slowo kluczowe required ulatwia proces zapewniania, ze wlasciwosci sa zawsze ustawione. Zamiast potrzebować konstruktorów dla metody set w każdym przypadku lub ryzykować niezdefiniowane właściwości, mamy teraz prosty sposób na wymaganie konkretnych wartości bezpośrednio w deklaracji właściwości.
Ta funkcja sprawdza się w modelach danych, w których niektóre pola są obowiązkowe, i może pomóc w wykryciu problemów na wczesnym etapie procesu programowania poprzez zapobieganie błędom null w czasie wykonywania.
Przykład dodatkowych właściwości
Nastepnie Tim dodal opcjonalna wlasciwosc, Email, ktora moze byc nullable:
public string? Email { get; set; }
public string? Email { get; set; }
Poniewaz nie jest oznaczona za pomoca required, wlasciwosc Email moze pozostac nieustawiona bez wywolywania bledu kompilatora. Na tym przykładzie Tim zademonstrował elastyczność, jaką zapewnia klasa z wyraźnym rozróżnieniem między polami danych niezbędnymi a opcjonalnymi.
Wnioski
Dodanie wymaganych właściwości w C# 11 jest cenną funkcją dla programistów, zapewniającą, że niezbędne właściwości są zawsze inicjowane. Film Tima Coreya stanowi doskonałe wprowadzenie do tej funkcji i pokazuje, jak działa ona w aplikacji konsolowej. Laczac slowo kluczowe required z inicjatorami obiektow i konstruktorami, mozemy tworzyc bardziej solidne i bezpieczniejsze modele danych w C#. Aby uzyskać więcej przydatnych samouczków, odwiedź kanał Tima na YouTube.
