Aktivering og forståelse af NRT
Aktivér nullable context, forstå nullable kontra non-nullable reference types, og læs compiler-advarsler.
Aktivering og forståelse af NRT er en gratis C# Academy-lektion på CoddyKit. Dette er lektion 1 af 4. Du kan læse hele lektionen gratis nedenfor — og derefter øve dig praktisk i browseren med en indbygget kodeeditor og en AI-vejleder, der er tilgængelig døgnet rundt. Den er en del af læringsforløbet i C# Academy, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. C# Academy-kurset indeholder 4 lektioner i alt.
Den milliarddyre fejl
Tony Hoare (opfinderen af null) kaldte det sin "milliarddyre fejl". I C# kunne enhver referencetype som standard være null, hvilket gjorde NullReferenceException til det mest almindelige nedbrud under kørsel. Nullbare referencetyper (NRT) løser problemet på kompilerniveau.
Aktivering af nullbarhedskonteksten
Aktivér NRT globalt i projektfilen eller pr. fil med direktiver. Når det er aktiveret, behandler kompileren referencetyper som ikke-nullbare som standard.
<!-- In .csproj — enable for the whole project -->
<PropertyGroup>
<Nullable>enable</Nullable>
</PropertyGroup>
// Or per-file:
#nullable enable
// ... code with NRT warnings
#nullable disable
// ... code without NRT warningsIkke-nullbare kontra nullbare referencetyper
Når NRT er aktiveret, betyder string, at værdien aldrig er null, mens string? betyder, at den kan være null. Kompileren advarer, hvis du tildeler null til en type, der ikke kan være null, eller derefererer en type, der kan være null, uden en kontrol.
#nullable enable
string nonNull = "Hello"; // OK
string? maybeNull = null; // OK — explicitly nullable
nonNull = null; // WARNING: CS8600
Console.WriteLine(maybeNull.Length); // WARNING: CS8602 — may be null
// Fix:
if (maybeNull is not null)
Console.WriteLine(maybeNull.Length); // safeFlowanalyse
Kompileren udfører flowanalyse — den sporer null-tilstanden gennem betingelser og grene og undertrykker advarsler, når den kan bevise, at en værdi ikke er null.
string? name = GetName();
// After null check, name is treated as non-null:
if (name is not null)
Console.WriteLine(name.Length); // no warning
// Same with early return:
if (name is null) return;
Console.WriteLine(name.Length); // no warning — null was returned
// Pattern matching:
if (name is string s)
Console.WriteLine(s.ToUpper()); // no warningAdvarsler om nullbarhed: CS8600–CS8629
Vigtige NRT-advarsler, du bør kende: CS8600 (tildeling af null til en type, der ikke kan være null), CS8602 (dereferering af en værdi, der muligvis er null), CS8603 (returnering af null for en type, der ikke kan være null), CS8618 (felt, der ikke er initialiseret, og som ikke kan være null).
#nullable enable
public class Order
{
public string CustomerName { get; set; } // CS8618: not initialized
public string? TrackingNumber { get; set; } // OK — nullable
public Order(string name)
{
CustomerName = name; // now initialized — CS8618 gone
}
}
string? s = GetValue();
Console.WriteLine(s.Length); // CS8602: s might be nullInitialisering af felter, der ikke kan være null
CS8618 opstår, når et felt eller en egenskab, der ikke kan være null, ikke sættes i konstruktøren. Løsningerne er at initialisere den i deklarationen, kræve den via konstruktøren eller bruge null-undertrykkelsesoperatoren til DI-/ORM-mønstre.
// Option 1: Initialize in declaration
public string Name { get; set; } = "";
// Option 2: Require via constructor
public class Product
{
public string Name { get; }
public Product(string name) => Name = name;
}
// Option 3: null-forgiving for ORM entities
public string Name { get; set; } = null!;
// null! tells compiler "trust me, this will be set by EF Core"Nullbarhed i generiske typer
Generiske typeparametre kan begrænses til ikke-nullbare typer. En where T : notnull-begrænsning sikrer, at T aldrig kan være null.
// Without constraint: T could be nullable
public T? Find<T>(int id) { ... }
// With notnull: T must be a non-nullable type
public T FindRequired<T>(int id) where T : notnull
{
var result = InternalFind<T>(id);
return result ?? throw new KeyNotFoundException();
}
// T? is meaningful only when T is known to be non-nullable
public T? FindOrDefault<T>(int id) where T : class { ... }Nullbarhed i grænseflader og tilsidesættelser
Når du implementerer en grænseflade eller tilsidesætter en metode, skal nullbarhedsmarkeringerne stemme overens. Kompileren kontrollerer, at implementeringerne er mindst lige så ikke-nullbare som grænsefladen angiver.
public interface IRepository<T>
{
T? FindById(int id); // may return null
T GetOrThrow(int id); // never null
}
// Implementation:
public class ProductRepo : IRepository<Product>
{
public Product? FindById(int id) => _db.Find(id);
public Product GetOrThrow(int id) =>
_db.Find(id) ?? throw new KeyNotFoundException();
}Nullbare værdityper kontra nullbare referencetyper
Forveksl ikke int? (Nullable<int> — en indpakning af en værditype, der fandtes før C# 8) med string? (en NRT-markering — kun ved kompilering og uden ekstra omkostninger under kørsel).
// Nullable value type (runtime Nullable<int>)
int? age = null;
bool hasValue = age.HasValue;
int value = age.GetValueOrDefault();
// Nullable reference type (compile-time annotation only)
string? name = null;
// string? has NO runtime wrapper — it's just a compile-time hint
// null check is still needed at runtime
if (name is not null)
Console.WriteLine(name.ToUpper());Undertryk advarsler med !
Null-undertrykkelsesoperatoren (!) undertrykker en bestemt nullbarhedsadvarsel, når du ved bedre end kompileren. Brug den sparsomt, og dokumentér, hvorfor det er sikkert.
// Use ! when you know the value cannot be null
var user = _db.Users.FirstOrDefault(u => u.Email == email);
var name = user!.Name; // user is guaranteed by business logic
// EF Core navigation properties set by the framework:
public class Order
{
public Customer Customer { get; set; } = null!; // set by EF Core
}Praktisk eksempel: nullbart API-svar
En API-wrapper, hvor felter måske er til stede i JSON-svaret eller måske ikke — nullbarhedsmarkeringer kommunikerer hensigten tydeligt.
#nullable enable
public class WeatherResponse
{
public string City { get; set; } = ""; // always present
public double Temperature { get; set; } // always present
public string? Description { get; set; } // optional field
public string? AlertMessage { get; set; } // only when there's an alert
}
// Consumer:
var weather = await api.GetWeatherAsync("London");
Console.WriteLine(weather.City); // safe
Console.WriteLine(weather.Description?.ToUpper() ?? "N/A"); // safe null-handlingHurtigt tjek
Hvilke ekstra omkostninger under kørsel har nullbare referencetyper (string?) sammenlignet med almindelige referencetyper (string)?
Opsummering: aktivering og forståelse af NRT
Vigtigste pointer:
- Aktivér globalt med
<Nullable>enable</Nullable>i .csproj string= aldrig null;string?= kan være null- Flowanalyse sporer null-tilstanden gennem grene og returneringer
- NRT-markeringer findes kun ved kompilering — ingen ekstra omkostninger under kørsel
- CS8618: initialisér felter, der ikke kan være null, i konstruktøren, eller brug
= null!til ORM - Brug ! sparsomt — dokumentér, hvorfor null-undertrykkelsen er sikker
Lær C# med en AI-underviser — gratis
Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.
- Kurser
- 93
- Lektioner
- 346
Ofte stillede spørgsmål
Er lektionen “Aktivering og forståelse af NRT” gratis?
Ja — hele teksten til “Aktivering og forståelse af NRT” kan læses gratis her på nettet. Hvis du vil øve dig interaktivt med en indbygget kodeeditor og en AI-vejleder døgnet rundt og få adgang til resten af C# Academy-kurset, skal du opgradere til CoddyKit PRO. C# Academy-kurset indeholder 4 lektioner i alt.
Hvad lærer jeg i “Aktivering og forståelse af NRT”?
Aktivér nullable context, forstå nullable kontra non-nullable reference types, og læs compiler-advarsler. Du øver dig i C# Academy med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.
Skal jeg have erfaring for at begynde på C# Academy?
Der kræves ingen tidligere erfaring. C# Academy på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 1 af 4.
Hvor lang tid tager lektionen “Aktivering og forståelse af NRT”?
De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.
Kan jeg skrive og køre kode i denne C# Academy-lektion?
Ja. Alle C# Academy-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.
Alle lektioner i dette kursus
- Aktivering og forståelse af NRT
- Annoteringer: ?, !, MaybeNull og NotNull
- Null-conditional- og null-coalescing-operatorer
- Migrering af en kodebase til NRT