C# Academy · Lektion

Aktivering og forståelse af NRT

Aktivér nullable context, forstå nullable kontra non-nullable reference types, og læs compiler-advarsler.

Lektion 1 af 413 trin

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 warnings

Ikke-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); // safe

Flowanalyse

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 warning

Advarsler 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 null

Initialisering 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-handling

Hurtigt 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
Gratis at komme i gang

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

  1. Aktivering og forståelse af NRT
  2. Annoteringer: ?, !, MaybeNull og NotNull
  3. Null-conditional- og null-coalescing-operatorer
  4. Migrering af en kodebase til NRT
← Tilbage til C# Academy