Megosztás a következőn keresztül:


Null értékű hivatkozástípusok

Nullable-oblivious környezetben minden referenciatípus null értékű volt. A null értékű hivatkozástípusok olyan, null értékű környezetben engedélyezett funkciókra utalnak, amelyek minimalizálják annak valószínűségét, hogy a kód a futtatókörnyezetet eldobja System.NullReferenceException. A null értékű hivatkozástípusok három olyan funkciót tartalmaznak, amelyek segítenek elkerülni ezeket a kivételeket, beleértve a hivatkozástípus null értékűként való explicit megjelölését is:

  • Továbbfejlesztett statikus folyamatelemzés, amely meghatározza, hogy egy változó lehet-e null a halasztás előtt.
  • Olyan attribútumok, amelyek az API-kat úgy jegyzetelik meg, hogy a folyamatelemzés null állapotot határozzon meg.
  • Változójegyzetek, amelyekkel a fejlesztők explicit módon deklarálják a kívánt null-állapotot egy változóhoz.

A fordító a kód minden kifejezésének null állapotát követi nyomon fordításkor. A null állapot három érték egyikével rendelkezik:

  • not-null: A kifejezés ismerten nem-null.
  • maybe-null: A kifejezés lehet null.
  • oblivious: A fordító nem tudja meghatározni a kifejezés null állapotát.

A változók széljegyzetei határozzák meg egy referenciatípus változó nullságát :

  • nem null értékű: Ha egy értéket vagy egy talán-null kifejezést rendel null a változóhoz, a fordító figyelmeztetést ad ki. A nem null értékű változók alapértelmezett null-állapota nem null.
  • null értékű: A változóhoz hozzárendelhet egy null értéket vagy egy talán-null kifejezést. Ha a változó null állapota talán null, a fordító figyelmeztetést ad ki, ha elhalasztja a változót. A változó alapértelmezett null állapota talán null.
  • oblivious: Hozzárendelhet egy null értéket vagy egy talán null kifejezést a változóhoz. A fordító nem ad ki figyelmeztetést, ha a változót elhalasztja, vagy ha egy esetleg null értékű kifejezést rendel hozzá a változóhoz.

Az oblivious null-state és az oblivious nullability megegyezik a null értékű hivatkozástípusok bevezetése előtti viselkedéssel. Ezek az értékek hasznosak a migrálás során, vagy ha az alkalmazás olyan kódtárat használ, amely nem engedélyezte a null értékű hivatkozástípusokat.

A nullállapot-elemzés és a változó széljegyzetek alapértelmezés szerint le vannak tiltva a meglévő projektek esetében, ami azt jelenti, hogy az összes referenciatípus továbbra is null értékű marad. A .NET 6-tól kezdve alapértelmezés szerint engedélyezve vannak az új projektekhez. A funkciók null értékű széljegyzetkörnyezet deklarálásával történő engedélyezéséről további információt a Null értékű környezetek című témakörben talál.

A cikk további része azt ismerteti, hogyan működik ez a három funkcióterület, hogy figyelmeztetéseket állítsunk elő, amikor a kód esetleg elhalaszt egy null értéket. Egy változó elhalasztása azt jelenti, hogy az egyik tagját a . (pont) operátorral érheti el, ahogyan az a következő példában látható:

string message = "Hello, World!";
int length = message.Length; // dereferencing "message"

Ha egy olyan változót halaszt el, amelynek az értéke, nulla futtatókörnyezet egy System.NullReferenceException.

A következő tudnivalókat fogja elsajátítani:

  • A fordító nullállapot-elemzése: hogyan határozza meg a fordító, hogy egy kifejezés nem null vagy esetleg null.
  • Olyan API-kra alkalmazott attribútumok , amelyek több kontextust biztosítanak a fordító nullállapot-elemzéséhez.
  • Null értékű változójegyzetek , amelyek információt nyújtanak a változók szándékáról. A széljegyzetek akkor hasznosak, ha a mezők az alapértelmezett nullállapotot állítják be a tagmetelyek elején.
  • Az általános típusú argumentumokat szabályozó szabályok. Új megkötések lettek hozzáadva, mert a típusparaméterek hivatkozástípusok vagy értéktípusok lehetnek. Az ? utótag a null értékű értéktípusok és a null értékű referenciatípusok esetében eltérően van implementálva.
  • A null értékű környezetek segítenek a nagy projektek migrálásában. Migráláskor engedélyezheti a null értékű környezeteket vagy figyelmeztetéseket az alkalmazás egyes részeiben. A további figyelmeztetések kezelése után engedélyezheti a teljes projekt null értékű hivatkozástípusait.

Végül megismerheti a nullállapot-elemzés ismert buktatóit a típusok és tömbök esetében struct .

Ezeket a fogalmakat a C# null értékű biztonságáról szóló Learn modulban is megismerheti.

nullállapot-elemzés

Ha engedélyezve vannak a null értékű hivatkozástípusok, a nullállapot-elemzés nyomon követi a hivatkozások null állapotát. A kifejezések nem null értékűek , vagy talán null értékűek. A fordító kétféleképpen állapítja meg, hogy egy változó nem null értékű:

  1. A változóhoz olyan érték lett hozzárendelve, amely ismerten nem null értékű.
  2. A változó ellenőrzése megtörtént null , és az ellenőrzés óta nem módosult.

Ha a null értékű hivatkozástípusok nincsenek engedélyezve, minden kifejezés null állapotú. A szakasz többi része azt a viselkedést ismerteti, amikor engedélyezve vannak a null értékű hivatkozástípusok.

A fordító által nem nullként meghatározott változók talán null értékűnek minősülnek. Az elemzés figyelmeztetéseket ad olyan helyzetekben, amikor véletlenül elhalaszthat egy null értéket. A fordító a null állapot alapján állít elő figyelmeztetéseket.

  • Ha egy változó nem null értékű, előfordulhat, hogy a változó biztonságosan el lesz hareferensítve.
  • Ha egy változó talán null értékű, a változót ellenőrizni kell, hogy null ne legyen a halasztás előtt.

Vegyük a következő példát:

string message = null;

// warning: dereference null.
Console.WriteLine($"The length of the message is {message.Length}");

var originalMessage = message;
message = "Hello, World!";

// No warning. Analysis determined "message" is not-null.
Console.WriteLine($"The length of the message is {message.Length}");

// warning!
Console.WriteLine(originalMessage.Length);

Az előző példában a fordító azt határozza meg, hogy message az első üzenet nyomtatásakor lehet-e null értékű. A második üzenetre nincs figyelmeztetés. A kód utolsó sora figyelmeztetést eredményez, mert originalMessage null értékű lehet. Az alábbi példa gyakorlatiasabb megoldást mutat be a csomópontok egy fájának a gyökérre való bejárására, és az egyes csomópontok feldolgozására a bejárás során:

void FindRoot(Node node, Action<Node> processNode)
{
    for (var current = node; current != null; current = current.Parent)
    {
        processNode(current);
    }
}

Az előző kód nem generál figyelmeztetést a változó currentelhalasztására. A statikus elemzés azt határozza meg, hogy current a rendszer soha nem hareferens, ha null értékű. A változót current null a rendszer a hozzáférés előtt current.Parent és a ProcessNode műveletre való current továbbítás előtt ellenőrzi. Az előző példák bemutatják, hogyan határozza meg a fordító a helyi változók null állapotát inicializálva, hozzárendelve vagy összehasonlítva null.

A nullállapot-elemzés nem nevezhető metódusoknak. Ennek eredményeképpen az összes konstruktor által hívott, közös segédmetódusban inicializált mezők a következő sablonnal generálnak figyelmeztetést:

A "name" nem null értékű tulajdonságnak nem null értéket kell tartalmaznia a konstruktorból való kilépéskor.

Ezek a figyelmeztetések kétféleképpen kezelhetők: konstruktorláncolás vagy null értékű attribútumok a segédmetóduson. Az alábbi kód mindegyikre mutat példát. Az Person osztály az összes többi konstruktor által hívott közös konstruktort használja. Az Student osztály egy segédmetódussal rendelkezik, amely a System.Diagnostics.CodeAnalysis.MemberNotNullAttribute következő attribútummal van eljegyzve:


using System.Diagnostics.CodeAnalysis;

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }

    public Person(string firstName, string lastName)
    {
        FirstName = firstName;
        LastName = lastName;
    }

    public Person() : this("John", "Doe") { }
}

public class Student : Person
{
    public string Major { get; set; }

    public Student(string firstName, string lastName, string major)
        : base(firstName, lastName)
    {
        SetMajor(major);
    }

    public Student(string firstName, string lastName) :
        base(firstName, lastName)
    {
        SetMajor();
    }

    public Student()
    {
        SetMajor();
    }

    [MemberNotNull(nameof(Major))]
    private void SetMajor(string? major = default)
    {
        Major = major ?? "Undeclared";
    }
}

Feljegyzés

A C# 10-ben számos fejlesztés történt a végleges hozzárendelés és a nullállapot-elemzés terén. A C# 10-re való frissítéskor kevesebb null értékű figyelmeztetés jelenhet meg, amelyek hamis pozitívak. A konkrét hozzárendelés-fejlesztések funkcióspecifikációjának továbbfejlesztéseiről bővebben is tájékozódhat.

A null értékű állapotelemzés és a fordító által generált figyelmeztetések segítenek elkerülni a programhibákat a halasztással null. A null értékű figyelmeztetések feloldásáról szóló cikk technikákat biztosít a kódban valószínűleg megjelenő figyelmeztetések kijavítására.

API-aláírások attribútumai

A nullállapot-elemzéshez fejlesztőktől származó tippekre van szükség az API-k szemantikájának megértéséhez. Egyes API-k null értékű ellenőrzéseket biztosítanak, és egy változó nullállapotát a maybe-null értékről a not-null értékre kell módosítani. Más API-k a bemeneti argumentumok null állapotától függően nem null vagy talán null értékű kifejezéseket adnak vissza. Vegyük például az alábbi kódot, amely nagybetűs üzenetet jelenít meg:

void PrintMessageUpper(string? message)
{
    if (!IsNull(message))
    {
        Console.WriteLine($"{DateTime.Now}: {message.ToUpper()}");
    }
}

bool IsNull(string? s) => s == null;

Az ellenőrzés alapján minden fejlesztő biztonságosnak tartja ezt a kódot, és nem generálhat figyelmeztetéseket. A fordító azonban nem tudja, hogy null IsNull értékű ellenőrzést biztosít, és figyelmeztetést ad ki az message.ToUpper() utasításhoz, figyelembe véve message , hogy lehet, hogy null értékű változó. A figyelmeztetés kijavításához használja az NotNullWhen attribútumot:

bool IsNull([NotNullWhen(false)] string? s) => s == null;

Ez az attribútum tájékoztatja a fordítót, hogy ha IsNull visszaadja false, a paraméter s nem null értékű. A fordító a blokkon belül nem null értékűre módosítja message a null állapototif (!IsNull(message)) {...}. A rendszer nem ad ki figyelmeztetést.

Az attribútumok részletes információkat nyújtanak az argumentumok null állapotáról, a visszatérési értékekről és a tag meghívásához használt objektumpéldány tagjairól. Az egyes attribútumok részletei a null értékű referenciaattribútumokról szóló nyelvi referenciacikkben találhatók. A .NET 5-ről az összes .NET futtatókörnyezeti API megjegyzést ad. A statikus elemzést úgy javíthatja, hogy az API-kat széljegyzetekkel javítja, hogy szemantikai információkat nyújtson az argumentumok nullállapotáról és az értékek visszaadásáról.

Null értékű változó széljegyzetei

A nullállapot-elemzés robusztus elemzést biztosít a helyi változókhoz. A fordítónak további információra van szüksége a tagváltozókról. A fordítónak további információra van szüksége ahhoz, hogy az összes mező nullállapotú legyen egy tag nyitó zárójelében. Bármelyik akadálymentes konstruktor használható az objektum inicializálására. Ha egy tagmező valaha is be van állítva, a fordítónak feltételeznie kell, hogy nullnull állapota az egyes metódusok elején talán null.

Olyan széljegyzeteket használ, amelyek deklarálhatják, hogy egy változó null értékű hivatkozástípus vagy nem null értékű hivatkozástípus. Ezek a széljegyzetek fontos állításokat tesznek a változók null állapotáról :

  • A hivatkozásnak nem szabad null értékűnek lennie. A nem null értékű referenciaváltozó alapértelmezett állapota nem null. A fordító olyan szabályokat kényszerít ki, amelyek biztosítják, hogy biztonságosan el lehessen halasztani ezeket a változókat anélkül, hogy először ellenőrizné, hogy nem null értékű-e:
    • A változót nem null értékűre kell inicializálni.
    • A változó soha nem rendelhető hozzá az értékhez null. A fordító figyelmeztetést ad ki, ha a kód egy talán null értékű kifejezést rendel egy olyan változóhoz, amely nem lehet null értékű.
  • A hivatkozás null értékű lehet. A null értékű referenciaváltozó alapértelmezett állapota talán-null. A fordító kényszeríti a szabályokat annak érdekében, hogy helyesen ellenőrizze a hivatkozásokat null :
    • A változó csak akkor lehet halasztva, ha a fordító garantálni tudja, hogy az érték nem null.
    • Ezek a változók inicializálhatók az alapértelmezett null értékkel, és más kódban is hozzárendelhetők az értékhez null .
    • A fordító nem ad ki figyelmeztetést, ha a kód egy null értékű változóhoz rendel egy talán null értékű kifejezést.

A nem null értékű referenciaváltozók alapértelmezett null állapota nem null. A null értékű referenciaváltozók kezdeti null-állapota talán-null.

A null értékű hivatkozástípus a null értékű értéktípusokkal megegyező szintaxissal van feljegyzve: ? a függvény hozzá van fűzve a változó típusához. A következő változódeklaráció például egy null értékű sztringváltozót jelöl: name

string? name;

Ha engedélyezve vannak a null értékű hivatkozástípusok, minden olyan változó, amelyben a ? típusnévhez nincs hozzáfűzve, nem null értékű hivatkozástípus. Ez magában foglalja a meglévő kód összes referenciatípus-változóját, miután engedélyezte ezt a funkciót. Az implicit módon beírt helyi változók (deklaráltak var) azonban null értékű referenciatípusok. Ahogy az előző szakaszok mutatták, a statikus elemzés meghatározza a helyi változók null állapotát , hogy megállapítsa , lehet-e null a halasztás előtt.

Néha felül kell bírálnia egy figyelmeztetést, ha tudja, hogy egy változó nem null, de a fordító megállapítja, hogy a null-állapota talán null. A null-elbocsátó operátort ! egy változó neve után használva kényszerítheti a null állapot nem null értékűre való kényszerítését. Ha például tudja, hogy a name változó nem null az, de a fordító figyelmeztetést ad ki, a következő kódot írhatja felül a fordító elemzésének felülbírálásához:

name!.Length;

A null értékű hivatkozástípusok és a null értékű értéktípusok hasonló szemantikai fogalmat biztosítanak: Egy változó egy értéket vagy objektumot jelölhet, vagy ez a változó lehet null. A null értékű referenciatípusok és a null értékű értéktípusok azonban eltérően vannak implementálva: a null értékű értéktípusok implementálása System.Nullable<T>a fordító által beolvasott attribútumokkal történik. Például, string? és string mindkettőt ugyanaz a típus képviseli: System.String. Azonban, int? és int képviselik System.Nullable<System.Int32> és System.Int32, illetve.

A null értékű hivatkozástípusok fordítási idő funkciónak számítanak. Ez azt jelenti, hogy a hívók figyelmen kívül hagyják a figyelmeztetéseket, szándékosan argumentumként használva null egy olyan metódushoz, amely nem null értékű hivatkozást vár. A kódtár-szerzőknek tartalmazniuk kell a null argumentumértékek futásidejű ellenőrzését. Ez ArgumentNullException.ThrowIfNull az előnyben részesített beállítás a paraméter null értékre való ellenőrzéséhez futásidőben.

Fontos

A null értékű széljegyzetek engedélyezése megváltoztathatja, hogy az Entity Framework Core hogyan határozza meg, hogy szükség van-e adattagra. További részleteket az Entity Framework Core alapjairól szóló cikkben talál: A null értékű referenciatípusok használata.

Generikus

Az általánosak részletes szabályokat igényelnek minden típusparaméter TkezeléséhezT?. A szabályok az előzmények és a null értékű értéktípusok eltérő implementációja és a null értékű hivatkozási típus miatt feltétlenül részletesek. A null értékű értéktípusok a System.Nullable<T> szerkezet használatával implementálhatók. A null értékű hivatkozástípusok olyan típusjegyzetekként vannak implementálva, amelyek szemantikai szabályokat biztosítanak a fordító számára.

  • Ha a típus argumentuma T hivatkozástípus, T? a megfelelő null értékű hivatkozástípusra hivatkozik. Ha például T egy string, akkor T? egy string?.
  • Ha a típusargumentum T egy értéktípus, T? ugyanazt az értéktípust használja. T Ha például T egy int, akkor az T? is egy int.
  • Ha a típusargumentum T null értékű hivatkozástípus, T? ugyanarra a null értékű hivatkozástípusra hivatkozik. Ha például T egy string?, akkor T? az is .string?
  • Ha a típusargumentum T null értékű, T? ugyanarra a null értékű típusra hivatkozik. Ha például T egy int?, akkor T? az is .int?

A visszatérési értékek T? esetében az argumentumértékek ; értékének felel [MaybeNull]Tmeg[AllowNull]T. T? További információ: Attribútumok a nullállapot-elemzéshez a nyelvi referenciaban.

A korlátozások használatával különböző viselkedést adhat meg:

  • A class kényszer azt jelenti, hogy T nem null értékű hivatkozástípusnak kell lennie (például string). A fordító figyelmeztetést hoz létre, ha null értékű hivatkozástípust használ, például string? a következőhöz T: .
  • A class? kényszer azt jelenti, hogy T referenciatípusnak kell lennie, vagy nem null értékű (string) vagy null értékű hivatkozástípusnak (például string?). Ha a típusparaméter null értékű hivatkozástípus, például string?olyan hivatkozási kifejezés T? , amely ugyanazzal a null értékű hivatkozástípussal rendelkezik, mint például string?.
  • A notnull kényszer azt jelenti, hogy T nem null értékű hivatkozástípusnak vagy nem null értékű értéktípusnak kell lennie. Ha null értékű hivatkozástípust vagy null értékű értéktípust használ a típusparaméterhez, a fordító figyelmeztetést hoz létre. Továbbá értéktípus esetén T a visszatérési érték az értéktípus, nem pedig a megfelelő null értékű típus.

Ezek a korlátozások további információt nyújtanak a fordítónak a használat módjáról T . Ez segít, ha a fejlesztők kiválasztják a típust T , és jobb nullállapot-elemzést biztosítanak az általános típus egy példányának használatakor.

Null értékű környezetek

Kis projektek esetén engedélyezheti a null értékű hivatkozástípusokat, kijavíthatja a figyelmeztetéseket és folytathatja a műveletet. A nagyobb projektek és a többprojektes megoldások esetében azonban ez számos figyelmeztetést eredményezhet. A pragmák használatával fájlonként engedélyezheti a null értékű hivatkozástípusokat a null értékű hivatkozástípusok használatának megkezdésekor. Az új funkciók, amelyek védelmet nyújtanak a System.NullReferenceException dobás ellen, zavaróak lehetnek, ha egy meglévő kódbázisban be van kapcsolva:

  • Minden explicit módon beírt referenciaváltozó nem null értékű referenciatípusként van értelmezve.
  • A kényszer jelentése az class általános értékekben nem null értékű hivatkozástípusra változott.
  • Az új szabályok miatt új figyelmeztetések jönnek létre.

A null értékű széljegyzetkörnyezet határozza meg a fordító viselkedését. A null értékű széljegyzetkörnyezetnek négy értéke van:

  • disable: A kód nullable-oblivious. Tiltsa le a null értékű hivatkozástípusok engedélyezése előtti viselkedést, kivéve, ha az új szintaxis hibák helyett figyelmeztetéseket hoz létre.
    • A null értékű figyelmeztetések le vannak tiltva.
    • Minden referenciatípus-változó null értékű referenciatípus.
    • ? Az utótag használata null értékű hivatkozástípus deklarálásához figyelmeztetést eredményez.
    • Használhatja a null elbocsátó operátort, !de nincs hatása.
  • engedélyezve: A fordító lehetővé teszi az összes nullhivatkozás-elemzést és az összes nyelvi funkciót.
    • Minden új null értékű figyelmeztetés engedélyezve van.
    • Az ? utótag használatával null értékű hivatkozástípust deklarálhat.
    • Az utótag nélküli ? referenciatípus-változók nem null értékű referenciatípusok.
    • A null elbocsátó operátor letiltja a figyelmeztetéseket egy lehetséges hozzárendeléshez null.
  • figyelmeztetések: A fordító végrehajtja az összes nullelemzést, és figyelmeztetéseket ad ki, amikor a kód elferdülhet null.
    • Minden új null értékű figyelmeztetés engedélyezve van.
    • ? Az utótag használata null értékű hivatkozástípus deklarálásához figyelmeztetést eredményez.
    • Minden referenciatípus-változó null értékű lehet. A tagok azonban az összes metódus nyitó zárójelében a not-null állapottal rendelkeznek, kivéve, ha az ? utótaggal van deklarálva.
    • A null elbocsátó operátort használhatja. !
  • széljegyzetek: A fordító nem ad ki figyelmeztetést, ha a kód elferdülhet null, vagy ha nem null értékű változóhoz rendel hozzá egy esetleg null értékű kifejezést.
    • Minden új null értékű figyelmeztetés le van tiltva.
    • Az ? utótag használatával null értékű hivatkozástípust deklarálhat.
    • Az utótag nélküli ? referenciatípus-változók nem null értékű referenciatípusok.
    • Használhatja a null elbocsátó operátort, !de nincs hatása.

A null értékű széljegyzetkörnyezet és a null értékű figyelmeztető környezet a .csproj fájl elemével állítható be egy <Nullable> projekthez. Ez az elem konfigurálja, hogy a fordító hogyan értelmezi a típusok nullképességét, és milyen figyelmeztetéseket ad ki. Az alábbi táblázat az engedélyezett értékeket mutatja be, és összegzi az általuk megadott környezeteket.

Környezet Halasztásra figyelmeztető figyelmeztetések Hozzárendelési figyelmeztetések Referenciatípusok ? toldalék ! operátor
disable Disabled (Letiltva) Disabled (Letiltva) Minden null értékű Figyelmeztetést hoz létre Nincs hatása
enable Engedélyezve Engedélyezve Nem null értékű, kivéve, ha ? Null értékű típust deklarál Letiltja a lehetséges null hozzárendelésre vonatkozó figyelmeztetéseket
warnings Engedélyezve Nem alkalmazható Mindegyik null értékű, de a tagok nem null értékűnek minősülnek a metódusok kapcsos zárójelének megnyitásakor Figyelmeztetést hoz létre Letiltja a lehetséges null hozzárendelésre vonatkozó figyelmeztetéseket
annotations Disabled (Letiltva) Disabled (Letiltva) Nem null értékű, kivéve, ha ? Null értékű típust deklarál Nincs hatása

A letiltott környezetben lefordított kód hivatkozástípus-változói null értékűek. Egy null értékű változóhoz literális vagy talán null értékű változót rendelhetnull. A null értékű változó alapértelmezett állapota azonban nem null.

Kiválaszthatja, hogy melyik beállítás a legmegfelelőbb a projekthez:

  • Válassza az olyan régi projektek letiltását , amelyeket nem szeretne frissíteni a diagnosztika vagy az új funkciók alapján.
  • A figyelmeztetések kiválasztásával meghatározhatja, hogy a kód hová kerülhetSystem.NullReferenceException. A nem null értékű hivatkozástípusok engedélyezéséhez a kód módosítása előtt kezelheti ezeket a figyelmeztetéseket.
  • A figyelmeztetések engedélyezése előtt válasszon széljegyzeteket a tervezési szándék kifejezéséhez.
  • Válassza az engedélyezés lehetőséget olyan új projektekhez és aktív projektekhez, amelyeknél védelmet szeretne nyújtani a nullhivatkozási kivételek ellen.

Példa:

<Nullable>enable</Nullable>

Az irányelvekkel ezeket a környezeteket a forráskód bármely pontján beállíthatja. Ezek az irányelvek akkor hasznosak, ha nagy kódbázist migrál.

  • #nullable enable: Beállítja a null értékű széljegyzetkörnyezetet és a null értékű figyelmeztető környezetet az engedélyezéshez.
  • #nullable disable: Beállítja a null értékű széljegyzetkörnyezetet és a null értékű figyelmeztető környezetet letiltásra.
  • #nullable restore: Visszaállítja a null értékű széljegyzetkörnyezetet és a null értékű figyelmeztető környezetet a projekt beállításaihoz.
  • #nullable disable warnings: Tiltsa le a null értékű figyelmeztetési környezetet.
  • #nullable enable warnings: Állítsa be a null értékű figyelmeztetési környezetet az engedélyezéshez.
  • #nullable restore warnings: Visszaállítja a null értékű figyelmeztető környezetet a projekt beállításaira.
  • #nullable disable annotations: Tiltsa le a null értékű széljegyzetkörnyezetet.
  • #nullable enable annotations: Állítsa be a null értékű széljegyzetkörnyezetet az engedélyezéshez.
  • #nullable restore annotations: Visszaállítja a széljegyzet figyelmeztetési környezetét a projekt beállításaihoz.

Bármely kódsorhoz a következő kombinációk bármelyikét állíthatja be:

Figyelmeztető környezet Széljegyzetkörnyezet Használat
projekt alapértelmezett beállítása projekt alapértelmezett beállítása Alapértelmezett
engedélyez letiltás Elemzési figyelmeztetések javítása
engedélyez projekt alapértelmezett beállítása Elemzési figyelmeztetések javítása
projekt alapértelmezett beállítása engedélyez Típusjegyzetek hozzáadása
engedélyez engedélyez A kód már migrálva van
letiltás engedélyez Kód jegyzetelése a figyelmeztetések javítása előtt
letiltás letiltás Örökölt kód hozzáadása a migrált projekthez
projekt alapértelmezett beállítása letiltás Ritkán
letiltás projekt alapértelmezett beállítása Ritkán

Ez a kilenc kombináció részletes vezérlést biztosít a fordító által a kódhoz kibocsátott diagnosztikák felett. A frissítendő területeken további funkciókat is engedélyezhet anélkül, hogy további figyelmeztetéseket látnál, amelyeket még nem tudsz kezelni.

Fontos

A globális null értékű környezet nem vonatkozik a létrehozott kódfájlokra. Mindkét stratégia esetében a null értékű környezet le van tiltva minden létrehozottként megjelölt forrásfájl esetében. Ez azt jelenti, hogy a létrehozott fájlokban lévő API-k nincsenek széljegyzetekkel elosztva. A fájlokat négyféleképpen lehet generáltként megjelölni:

  1. A .editorconfig fájlban adja meg generated_code = true az adott fájlra vonatkozó szakaszt.
  2. Tegyen <auto-generated> vagy <auto-generated/> írjon megjegyzést a fájl tetején. A megjegyzés bármely sorában szerepelhet, de a megjegyzésblokknak a fájl első elemének kell lennie.
  3. Indítsa el a fájlnevet TemporaryGeneratedFile_
  4. Fejezze be a fájlnevet .designer.cs, .generated.cs, .g.cs vagy .g.i.cs.

A generátorok az előfeldolgozási #nullable irányelv használatával is bejelentkezhetnek.

Alapértelmezés szerint a null értékű széljegyzetek és a figyelmeztető környezetek le vannak tiltva. Ez azt jelenti, hogy a meglévő kód módosítások nélkül és új figyelmeztetések létrehozása nélkül fordítható le. A .NET 6-tól kezdődően az új projektek az összes projektsablonban tartalmazzák az <Nullable>enable</Nullable> elemet.

Ezek a lehetőségek két különböző stratégiát biztosítanak egy meglévő kódbázis null értékű referenciatípusok használatára való frissítéséhez.

Ismert buktatók

A hivatkozástípusokat tartalmazó tömbök és szerkezetek ismert buktatók a null értékű hivatkozásokban, valamint a null biztonságot meghatározó statikus elemzések. Mindkét esetben előfordulhat, hogy nulla nem null értékű hivatkozás inicializálva lesz, figyelmeztetések létrehozása nélkül.

Struktúrák

A nem null értékű hivatkozástípusokat tartalmazó struktúra figyelmeztetések nélkül teszi lehetővé a hozzárendelést default . Vegyük a következő példát:

using System;

#nullable enable

public struct Student
{
    public string FirstName;
    public string? MiddleName;
    public string LastName;
}

public static class Program
{
    public static void PrintStudent(Student student)
    {
        Console.WriteLine($"First name: {student.FirstName.ToUpper()}");
        Console.WriteLine($"Middle name: {student.MiddleName?.ToUpper()}");
        Console.WriteLine($"Last name: {student.LastName.ToUpper()}");
    }

    public static void Main() => PrintStudent(default);
}

Az előző példában PrintStudent(default) nincs figyelmeztetés, amíg a nem null értékű hivatkozástípusok FirstName LastName null értékűek.

Egy másik gyakori eset, amikor általános szerkezetekkel foglalkozik. Vegyük a következő példát:

#nullable enable

public struct S<T>
{
    public T Prop { get; set; }
}

public static class Program
{
    public static void Main()
    {
        string s = default(S<string>).Prop;
    }
}

Az előző példában a tulajdonság Prop futásidőben van null . Nem null értékű sztringhez van rendelve figyelmeztetés nélkül.

Tömbök

A tömbök a null értékű referenciatípusok ismert buktatói is. Tekintse meg az alábbi példát, amely nem eredményez figyelmeztetést:

using System;

#nullable enable

public static class Program
{
    public static void Main()
    {
        string[] values = new string[10];
        string s = values[0];
        Console.WriteLine(s.ToUpper());
    }
}

Az előző példában a tömb deklarációja azt mutatja, hogy nem null értékű sztringeket tartalmaz, míg elemei mind inicializálva vannak.null Ezután a változóhoz s hozzá lesz rendelve egy null érték (a tömb első eleme). Végül a változó s hareferens, futásidejű kivételt okoz.

Lásd még