1. Wprowadzenie
Dlaczego NRT trzeba włączać osobno?
Nullable Reference Types (NRT) — to nie tylko syntactic sugar, ale konkretny pomocnik kompilatora w walce z błędami związanymi z null. Ale z historycznych powodów ten tryb nie jest domyślnie włączony we wszystkich starych projektach — żeby nie rozwalić kompatybilności. Jeśli tworzysz nowy projekt w najnowszych wersjach .NET (np. .NET 7, 8 albo 9), to NRT najpewniej już są włączone automatycznie. Ale jeśli projekt jest starszy albo chcesz tym trybem zarządzać ręcznie, trzeba to zrobić jawnie.
Co robi tryb Nullable Reference Types?
Gdy ten tryb jest aktywny, kompilator zaczyna analizować, które zmienne referencyjne mogą być równe null, a które nie. Nie wpływa to na samo wykonanie programu, ale sypie ostrzeżeniami, jeśli widzi potencjalny błąd. To świetny sposób, żeby pisać solidny, czytelny i odporny kod.
Jak sprawdzić, czy tryb NRT jest włączony?
Jeśli masz nowy projekt .NET 6 albo wyżej, najpewniej NRT już są włączone. Ale różnie bywa. Sprawdźmy!
- Otwórz plik projektu. Zwykle to plik z rozszerzeniem .csproj.
- Znajdź albo dodaj ustawienie <Nullable> wewnątrz pierwszego taga <PropertyGroup>.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>
Jeśli tam jest <Nullable>disable</Nullable>, to znaczy, że kontrola NRT jest wyłączona.
2. Jak włączyć tryb NRT
Przez .csproj — dla całego projektu
- Otwórz (albo stwórz) plik .csproj.
- Wewnątrz bloku <PropertyGroup> dodaj albo zmień linię:
<Nullable>enable</Nullable>
Teraz kompilator będzie pilnował wszystkich .cs-plików w projekcie i narzekał na potencjalnie niebezpieczne odwołania do null.
Po co tak robić?
Bo to globalne ustawienie. Od tej pory cały projekt działa według nowych zasad: null — pod lupą, a bylejakość już nie przejdzie!
Tylko dla pojedynczych plików albo kawałków kodu
Jeśli jeszcze nie jesteś gotowy na tryb restrykcyjny dla całego projektu, możesz poćwiczyć na pojedynczych plikach. Do tego służą dyrektywy preprocesora:
#nullable enable
string? value = null; // Tutaj analiza włączona
#nullable disable
string legacyValue = null; // A tutaj — już nie
#nullable restore
- #nullable enable — włącza sprawdzanie do końca pliku.
- #nullable disable — wyłącza je.
- #nullable restore — przywraca ustawienia z .csproj albo zewnętrznego pliku.
To wygodne: możesz włączyć restrykcyjną kontrolę w nowych modułach, nie ruszając starego, niestabilnego kodu.
Co jeszcze można wpisać w <Nullable>
| Wartość | Zachowanie |
|---|---|
|
Włącza wszystko: adnotacje i ostrzeżenia |
|
Całkowicie wyłącza analizę null-referencji |
|
Tylko ostrzeżenia, bez obowiązkowych adnotacji |
|
Adnotacje są wymagane, ale kompilator nie będzie narzekał |
|
Przywraca zachowanie do domyślnego (np. z globalnego ustawienia) |
Zwykle używa się enable albo disable.
3. Demonstracja na przykładzie
Przed włączeniem NRT
// Stary tryb, NRT wyłączone
string s = null; // Zero narzekań
Console.WriteLine(s.Length); // Niebezpieczne! Możliwy NullReferenceException
Po włączeniu NRT
// Nowy tryb, NRT włączone
string s = null; // Warning: możliwe przypisanie null
Console.WriteLine(s.Length); // Warning: możliwe odwołanie do null
Teraz IDE zacznie podkreślać potencjalne problemy, a kompilator ostrzeże: Dereference of a possibly null reference. (CS8602)
Jak to naprawić?
string? s = null;
if (s != null)
{
Console.WriteLine(s.Length);
}
Tak jasno pokazujesz: ta zmienna może być null, i kompilator jest zadowolony.
4. Co zrobić, jeśli projekt jest napisany "po staremu"?
Wiele projektów powstało w czasach, gdy null był praktycznie w każdej zmiennej referencyjnej. Włączając NRT, jakbyś zatrudniał surowego rewizora, który zgłosi każdą potencjalną wtopę.
A jeśli ostrzeżeń jest za dużo?
Bez paniki — to nie są błędy, tylko podpowiedzi. Program dalej się kompiluje.
- Możesz włączać NRT tylko w nowych plikach.
- Stopniowo ogarniaj kod: dodawaj ?, rób sprawdzenia na null, używaj ! (o tym później).
- Pamiętaj: im staranniej obchodzisz się z null, tym mniej problemów później.
Wsteczna kompatybilność i zewnętrzne biblioteki
- Włączenie NRT nie zmienia działania kodu w czasie uruchomienia, tylko dodaje analizę na etapie kompilacji.
- Stary kod może od razu wywalić dużo ostrzeżeń.
- Jeśli używasz bibliotek bez adnotacji NRT, kompilator będzie ostrożny i założy, że wszystko może być null.
GO TO FULL VERSION