Migracja bazy kodu do NRT
Zastosuj etapową strategię migracji: włącz ostrzeżenia, dodaj adnotacje do API, napraw problemy i unikaj fałszywych alarmów.
Migracja bazy kodu do NRT to bezpłatna lekcja C# Academy na CoddyKit. To lekcja 4 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej C# Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs C# Academy zawiera 4 lekcji w sumie.
Wyzwanie związane z migracją
Włączenie NRT w istniejącej bazie kodu zazwyczaj powoduje pojawienie się setek ostrzeżeń. Podejście typu big bang jest ryzykowne. Zamiast tego należy zastosować migrację etapową: stopniowo włączać ostrzeżenia, naprawiać je plik po pliku i nie tracić tempa prac.
Krok 1: Włączenie tylko ostrzeżeń
Na początku należy użyć <Nullable>warnings</Nullable> zamiast enable. Spowoduje to włączenie ostrzeżeń bez traktowania nieoznaczonego kodu jako błędów — to bezpieczny punkt wyjścia.
<!-- Phase 1: warnings only, no breaking change -->
<PropertyGroup>
<Nullable>warnings</Nullable>
</PropertyGroup>
<!-- Phase 2: full enable per file as you migrate -->
<!-- Phase 3: switch to enable globally when done -->Krok 2: Włączanie dla poszczególnych plików
Podczas pracy nad kolejnymi plikami należy umieszczać na ich początku #nullable enable. Ogranicza to zmiany do aktualnie edytowanych plików i ułatwia przeprowadzanie przeglądów kodu.
#nullable enable
// Now this file has full NRT analysis
public class OrderService
{
private readonly IOrderRepository _repo;
// Compiler now warns about uninitialized non-nullable fields,
// unsafe dereferences, and assignment to non-nullable
public OrderService(IOrderRepository repo) => _repo = repo;
}
// Other files without #nullable enable are still uncheckedKategoryzowanie ostrzeżeń
Ostrzeżenia dzielą się na dwie kategorie: bezpieczne do wyciszenia (encje ORM, pola wstrzykiwane przez DI) oraz rzeczywiste błędy (wartości, które faktycznie mają wartość null i są dereferencjonowane). Przed wyciszeniem ostrzeżeń należy je rozróżnić.
// Category 1: safe to suppress with null!
// EF Core navigation properties — set by EF, never null in practice
public class Order
{
public Customer Customer { get; set; } = null!;
}
// Category 2: real bug — must fix
public string GetFullName()
{
return FirstName + " " + LastName; // LastName was string? -- BUG!
}Naprawianie ostrzeżenia konstruktora CS8618
CS8618 jest zgłaszane, gdy właściwość, która nie może mieć wartości null, nie zostanie ustawiona w konstruktorze. Preferowanym rozwiązaniem jest wymaganie jej w konstruktorze. = null! należy stosować wyłącznie w przypadku wartości ustawianych przez framework.
// BEFORE (CS8618)
public class Product
{
public string Name { get; set; } // warning
public Category Category { get; set; } // warning
}
// AFTER — constructor required:
public class Product
{
public string Name { get; set; }
public Category Category { get; set; }
public Product(string name, Category category)
{
Name = name;
Category = category;
}
}Obsługa starszych interfejsów API
Interfejsy API firm trzecich lub starsze interfejsy API mogą nie zawierać adnotacji. Typy zwracane przez takie interfejsy są oblivious (ani nullable, ani non-nullable). Aby wyraźnie to zaznaczyć, należy przypisywać ich wyniki do zmiennych typu nullable.
// Legacy API returns 'string' but might be null (oblivious type)
string? legacyResult = OldLibrary.GetValue(); // store as nullable
if (legacyResult is null) return;
// Or convert at the boundary:
string safe = OldLibrary.GetValue() ?? "";
// For third-party types, check if they have NRT annotations:
// NuGet packages often add nullable annotations in newer versionsUżywanie #pragma do wyciszania określonych ostrzeżeń
Gdy ostrzeżenie jest rzeczywiście fałszywym alarmem, a zapis = null! wydaje się zbyt mało czytelny, należy użyć #pragma warning disable z zakresem ograniczonym do konkretnego wiersza.
// Suppress for a specific case with explanation:
#pragma warning disable CS8618 // ORM populates this via reflection
public DbSet<Product> Products { get; set; }
#pragma warning restore CS8618
// Or inline with a comment:
public DbSet<Order> Orders { get; set; } = null!; // set by EF CoreTraktowanie ostrzeżeń NRT jako błędów
Po naprawieniu wszystkich ostrzeżeń w pliku należy dodać <WarningsAsErrors>Nullable</WarningsAsErrors> (lub zastosować wymuszanie w CI), aby zapobiec regresjom — każdy nowy problem związany z nullable spowoduje niepowodzenie kompilacji.
<!-- After full migration: treat nullable warnings as build errors -->
<PropertyGroup>
<Nullable>enable</Nullable>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<!-- Or selectively: -->
<!-- <WarningsAsErrors>CS8600;CS8602;CS8603</WarningsAsErrors> -->
</PropertyGroup>Adnotowanie publicznych interfejsów API
Gdy z biblioteki korzystają inni programiści, adnotacje NRT stają się częścią kontraktu jej publicznego interfejsu API. Należy zwracać T?, gdy wynik może mieć wartość null, oraz T, gdy jest ona gwarantowana.
public interface IProductService
{
// Contract: FindById MAY return null, GetById never does
Product? FindById(int id);
Product GetById(int id); // throws if not found
// Collection: never null (may be empty)
IReadOnlyList<Product> GetAll();
// String: may be empty but not null
string GetSummary(int id);
}Metryki i śledzenie postępów migracji
Postępy można śledzić, zliczając pliki zawierające #nullable enable lub uruchamiając w CI polecenie dotnet build 2>&1 | grep CS86. Należy wyznaczyć docelową datę zakończenia migracji całego projektu.
# Count NRT warnings in current build
dotnet build 2>&1 | grep -c 'CS860[0-9]\|CS861[0-9]\|CS862[0-9]'
# List files still missing #nullable enable
grep -rL '#nullable enable' src/ --include='*.cs'
# Track in CI: fail if warning count increases
# Set a budget: warnings <= N, where N decreases each sprintSzybkie sprawdzenie
Co komunikuje przypisanie = null! właściwości, która nie może mieć wartości null?
Podsumowanie: Migracja do NRT
Najważniejsze informacje:
- Należy stosować migrację etapową: tryb ostrzeżeń → włączanie dla poszczególnych plików → włączenie globalne
- Należy odróżniać rzeczywiste błędy (które trzeba naprawić) od wzorców ORM/DI (w których można użyć
= null!) - CS8618 należy naprawiać, wymagając wartości w konstruktorach, a nie przez wyciszanie ostrzeżeń
- Wyniki starszych interfejsów API należy przypisywać do zmiennych typu
T?, aby wyraźnie określić ich charakter - W CI należy traktować ostrzeżenia dotyczące nullable jako błędy, aby zapobiegać regresjom
- Adnotowane publiczne interfejsy API stają się jasnymi kontraktami dla użytkowników
Często zadawane pytania
Czy lekcja „Migracja bazy kodu do NRT” jest bezpłatna?
Tak — pełny tekst „Migracja bazy kodu do NRT” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu C# Academy, przejdź na CoddyKit PRO. Kurs C# Academy zawiera 4 lekcji w sumie.
Co nauczysz się w „Migracja bazy kodu do NRT”?
Zastosuj etapową strategię migracji: włącz ostrzeżenia, dodaj adnotacje do API, napraw problemy i unikaj fałszywych alarmów. Ćwiczysz C# Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć C# Academy?
Nie wymagamy żadnego doświadczenia. C# Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 4 z 4.
Ile czasu zajmuje lekcja „Migracja bazy kodu do NRT”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji C# Academy?
Tak. Każda lekcja C# Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- Włączanie i poznawanie NRT
- Adnotacje: ?, !, MaybeNull i NotNull
- Operatory null-conditional i null-coalescing
- Migracja bazy kodu do NRT