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


Null értékű figyelmeztetések feloldása

A null értékű figyelmeztetések célja, hogy minimalizálják annak az esélyét, hogy az alkalmazás futtatáskor adódik System.NullReferenceException . A cél elérése érdekében a fordító statikus elemzést használ, és figyelmeztetéseket ad ki, ha a kód olyan szerkezeteket tartalmaz, amelyek nullhivatkozási kivételekhez vezethetnek. Típusjegyzetek és attribútumok alkalmazásával információkat adhat meg a fordítónak a statikus elemzéshez. Ezek a széljegyzetek és attribútumok az argumentumok, paraméterek és a típusok tagjainak nullbilitását írják le. Ebben a cikkben különböző technikákat ismerhet meg a fordító által a statikus elemzésből generált null értékű figyelmeztetések kezelésére. Az itt ismertetett technikák az általános C# kódhoz tartoznak. Ismerje meg a null értékű referenciatípusok és az Entity Framework core használatát a null értékű referenciatípusok használata során.

A null értékű hivatkozástípusok, beleértve a ? és a ! operátorokat is, csak akkor engedélyezettek, ha a null értékű környezet enable vagy annotationsértékre van állítva. A null értékre vonatkozó környezetet a projektfájlban aNullable fordítóbeállítás segítségével vagy a forráskódban a #nullable pragmával állíthatja be.

Ez a cikk az alábbi fordítói figyelmeztetéseket ismerteti:

  • CS8598 - A letiltási operátor ebben a környezetben nem engedélyezett
  • CS8601 - Lehetséges nullhivatkozás-hozzárendelés.
  • CS8602 - Lehetséges nullhivatkozás megszüntetése.
  • CS8604 - Lehetséges nullhivatkozási argumentum a paraméterhez.
  • CS8605 - Lehetséges null érték kicsomagolása.
  • CS8608 - A referenciatípusok nullíthatósága a típusban nem egyezik a felülírt taggal.
  • CS8609: A hivatkozástípusok nullázhatósága a visszatérési típusban nem egyezik meg a felülírt taggal.
  • CS8610A hivatkozástípusok nullabilitása a típusparaméterben nem egyezik meg a felülírt taggal.
  • A típusparaméterben lévő referenciatípusok nullázhatósága - nem egyezik a részleges metódusdeklarációval.
  • CS8612 - A referenciatípusok nullázhatósága a típusban nem egyezik az implicit módon implementált taggal.
  • CS8613A hivatkozási típusok visszatérési típusának nullázási képessége nem egyezik meg az implicit módon implementált taggal.
  • CS8614 - A paraméter típusában található hivatkozástípusok nullabilitása nem egyezik az implicit módon implementált taggal.
  • CS8615 - A referencia típusok nullázhatósága nem egyezik az implementált taggal.
  • CS8616 - A visszatérési típus referenciatípusainak nullérzékenysége nem egyezik a megvalósított taggal.
  • A paraméter típusában a hivatkozástípusok nullabilitása nem egyezik az implementált tag nullabilitásával. CS8617
  • A CS8618 - Nem null értékű változónak nem null értéket kell tartalmaznia, amikor kilép a konstruktorból. Fontolja meg, hogy a változót null értékűként deklarálja.
  • CS8620 - Az argumentum nem használható a paraméterhez a hivatkozástípusok nullázhatósága közötti különbségek miatt.
  • A visszatérési típus referenciatípusának nullsága nem egyezik meg a céldelegált elvárásaival (esetleg a nullságot kezelő attribútumok miatt).
  • CS8622 - A paraméter típusában található hivatkozástípusok nullabilitása nem egyezik meg a céldelegált nullabilitásával (valószínűleg a nullabilitási attribútumok miatt).
  • CS8623 - System.Runtime.CompilerServices.NullableAttribute explicit alkalmazása nem engedélyezett.
  • A CS8624 - argumentum nem használható kimenetként a hivatkozástípusok nullbilitásának különbségei miatt.
  • CS8628 - Nem használható null értékű hivatkozástípus az objektum létrehozásakor.
  • A CS8629 - nullálható értéktípus null értékű lehet.
  • CS8632 - A null értékű hivatkozástípusok jegyzeteit csak a #nullable széljegyzetek környezetében lévő kódban szabad használni.
  • A CS8633 a metódus típusparaméterének kényszereiben nem egyezik meg az interfészmetódus típusparaméterére vonatkozó korlátozásokkal. Fontolja meg inkább egy explicit interfészimplementáció használatát.
  • CS8636 - Érvénytelen beállítás a /nullableszámára; kell, hogy disable, enable, warnings vagy annotations legyen
  • CS8637 - Várt enable, disablevagy restore
  • CS8639 - A típusművelet nem használható null értékű hivatkozástípuson
  • CS8643 - A referenciatípusok nullabilitása az explicit interfészjelölőben nem egyezik az interfésszel, amelyet a típus implementál.
  • A típus nem implementálja az interfész tagját. Az alaptípus által implementált interfészben lévő referenciatípusok nullálhatósága nem egyezik meg.
  • A CS8645A tag már szerepel az interfészlistában a típuson eltérő nullázhatóságú hivatkozástípus mellett.
  • A CS8667 - részleges metódus deklarációi típusparaméterek korlátaiban inkonzisztens nullabilitással rendelkeznek.
  • A CS8670 - Az objektum- vagy gyűjtemény-inicializáló közvetlenül hivatkozik egy esetlegesen null tagra.
  • CS8763 - A megjelölt [DoesNotReturn] metódus nem térhet vissza.
  • A CS8764 - A visszatérési típus nullabilitása nem egyezik a felülírt tag nullabilitásával (valószínűleg nullability attribútumok miatt).
  • A CS8765 - paramétertípus nullabilitása nem egyezik a felülírt taggal (valószínűleg a nullabilitási attribútumok miatt).
  • CS8766 - A visszatérési típus referencia-típusainak nullabilitása nem egyezik az implicit módon implementált tag nullabilitásával (valószínűleg a nullabilitási attribútumok miatt).
  • CS8767 -
  • CS8768 - A visszatérési típus referencia típusainak nullérték kezelése nem egyezik meg a megvalósított tagéval (valószínűleg a nullérték kezelési attribútumok miatt).
  • CS8769 referencia típusok nullabilitása a paraméter típusában - nem egyezik meg az implementált tagéval (esetleg a nullabilitási attribútumok miatt).
  • CS8775 tagnaknem lehet null értéke a kilépéskor.
  • CS8819 - A visszatérési típus referenciatípusának nullázhatósága nem egyezik a részleges metódus deklarációjával.

Jegyzet

A statikus elemzés nem mindig tud arra következtetni, hogy egy adott forgatókönyvben milyen sorrendben érhetők el a metódusok, és hogy a metódus sikeresen befejeződik-e kivétel nélkül. Ezeket az ismert buktatókat Ismert buktatók szakaszban ismertetjük.

Az öt technika egyikével szinte az összes figyelmeztetést kezeli:

  • A null értékű környezet konfigurálása.
  • A szükséges null-ellenőrzések hozzáadása.
  • ? vagy ! null értékű széljegyzetek hozzáadása vagy eltávolítása.
  • Null szemantikát leíró attribútumok hozzáadása.
  • A változók inicializálása helyesen.

Ha még nem használja a null értékű hivatkozástípusokat, a null értékű hivatkozástípusok áttekintése hátteret biztosít a null értékű referenciatípusok megoldásához, valamint a kódok esetleges hibáira vonatkozó figyelmeztetések biztosításához. Az null értékű hivatkozástípusokra való migrálásra vonatkozó útmutatást is megtekintheti, ha többet szeretne megtudni arról, hogyan engedélyezheti a null értékű referenciatípusokat egy meglévő projektben.

Null értékű környezet konfigurálása

Az alábbi figyelmeztetések arra utalnak, hogy helytelenül állította be a nullálható kontextust:

  • CS8632 - A null értékű hivatkozástípusok jegyzeteit csak a #nullable széljegyzetek környezetében lévő kódban szabad használni.
  • CS8636 - Érvénytelen opció /nullable; disable, enable, warnings vagy annotations
  • CS8637 - Elvárt enable, disablevagy restore
  • CS8668 - Várt warnings, annotationsvagy az irányelv vége

A nullálható környezet helyes beállításához két lehetősége van:

  1. Projektszintű konfiguráció: Adja hozzá az <Nullable> elemet a projektfájlhoz:

    <PropertyGroup>
     <Nullable>enable</Nullable>
    </PropertyGroup>
    
  2. Fájlszintű konfiguráció: Használjon #nullable előfeldolgozási irányelveket a forráskódban:

    #nullable enable
    

A null értékű környezet két független jelzővel rendelkezik, amelyek különböző szempontokat szabályoznak:

  • Széljegyzetjelző: Azt határozza meg, hogy használható-e ? nullázható hivatkozás típusok deklarálásához és ! az egyes figyelmeztetések elnyomásához.
  • Figyelmeztető jelző: Azt szabályozza, hogy a fordító null értékű figyelmeztetéseket bocsát-e ki

A null értékű környezetekről és a migrálási stratégiákról az alábbiakban talál részletes információt.

Helytelen széljegyzetszintaxis

Ezek a hibák és figyelmeztetések azt jelzik, hogy a ! vagy ? széljegyzet használata helytelen.

  • CS8598 - A letiltási operátor ebben a környezetben nem engedélyezett,
  • CS8623 - System.Runtime.CompilerServices.NullableAttribute explicit alkalmazása nem engedélyezett.
  • CS8628 - Objektumlétrehozáskor nem használható null értékű hivatkozástípus.
  • CS8639 - A típusművelet nem használható null értékű hivatkozástípuson

A deklaráció ? megjegyzése azt jelzi, hogy a változó null értékű lehet. Nem jelez másik futtatókörnyezet-típust. A következő deklarációk megegyeznek a futtatókörnyezet típusával:

string s1 = "a string";
string? s2 = "another string";

A ? egy tipp a fordító számára a null értékek várhatóságáról.

Egy kifejezés ! széljegyzete azt jelzi, hogy tudja, hogy a kifejezés biztonságos, és feltételezni kell, hogy nem null értékű.

  • Ezeket a megjegyzéseket kell használnia, nem a System.Runtime.CompilerServices.NullableAttribute kódot.
  • Mivel a ? nem típus, hanem széljegyzet, nem használható typeofvagy new kifejezésekkel.
  • A ! operátor nem alkalmazható változókifejezésre vagy metóduscsoportra.
  • A ! operátor nem alkalmazható a tagelérési operátor bal oldalán, például obj.Field!.Method().

A null lehetséges halasztása

Ezek a figyelmeztetések arra figyelmeztetik, hogy egy olyan változót dereferál, amelynek null állapotalehet null. Ezek a figyelmeztetések a következők:

  • CS8602 - Lehetséges null értékű hivatkozás feloldása.
  • A CS8670 - Objektum- vagy gyűjtemény-inicializáló implicit módon egy lehetségesen null értékű tagra hivatkozik.

Az alábbi kód az előző figyelmeztetések mindegyikére egy-egy példát mutat be:

class Container
{
    public List<string>? States { get; set; }
}

internal void PossibleDereferenceNullExamples(string? message)
{
    Console.WriteLine(message.Length); // CS8602

    var c = new Container { States = { "Red", "Yellow", "Green" } }; // CS8670
}

Az előző példában a figyelmeztetés az, hogy a Container, cnull értékkel rendelkezhet a States tulajdonsághoz. Ha új állapotokat rendel egy null értékű gyűjteményhez, az a figyelmeztetést okozza.

A figyelmeztetések eltávolításához hozzá kell adnia kódot, hogy a változó null állapota változzon nem-null állapotra, mielőtt dereferálást végezne. A gyűjtemény inicializáló figyelmeztetését nehezebb észrevenni. A fordító észleli, hogy a gyűjtemény esetlegesen null lesz, amikor az inicializáló elemeket ad hozzá.

Számos esetben kijavíthatja ezeket a figyelmeztetéseket azzal, hogy ellenőrzi, hogy egy változó nem null értékű-e, mielőtt derezzük. Tekintse meg az alábbi példát, amely null értékű ellenőrzést ad hozzá a message paraméter elhalasztása előtt:

void WriteMessageLength(string? message)
{
    if (message is not null)
    {
        Console.WriteLine(message.Length);
    }
    
}

Az alábbi példa inicializálja a háttértárat States, és eltávolítja a hozzáférőt set. Az osztály felhasználói módosíthatják a gyűjtemény tartalmát, és a gyűjtemény tárterülete soha nem null:

class Container
{
    public List<string> States { get; } = new();
}

Más helyzetekben, amikor ezeket a figyelmeztetéseket kapja, előfordulhat, hogy téves riasztások. Lehet, hogy rendelkezik egy privát segédprogrammal, amely null értéket tesztel. A fordító nem tudja, hogy a metódus null értékű ellenőrzést biztosít. Vegye figyelembe az alábbi példát, amely egy privát segédfüggvényt használ: IsNotNull

public void WriteMessage(string? message)
{
    if (IsNotNull(message))
        Console.WriteLine(message.Length);
}

A fordító figyelmeztet, hogy lehet, nulláris értékre hivatkozik, amikor a(z) message.Length tulajdonságot írja, mert a statisztikai elemzése azt határozza meg, hogy message lehet null. Ön tudja, hogy a IsNotNull nullérték-ellenőrzést biztosít, és amikor true-et ad vissza, a message nullállapotnak nem-nullánakkell lennie. Ezeket a tényeket el kell mondania a fordítónak. Ennek egyik módja a null elbocsátó operátor használata. ! Úgy módosíthatja a WriteLine utasítást, hogy az megfeleljen a következő kódnak:

Console.WriteLine(message!.Length);

A null forgiváló operátor a kifejezést nem-null értékűvé teszi akkor is, ha az alkalmazás nélkül esetleg null értékű volt. Ebben a példában jobb megoldás, ha egy attribútumot ad hozzá a következő aláírásához IsNotNull:

private static bool IsNotNull([NotNullWhen(true)] object? obj) => obj != null;

A System.Diagnostics.CodeAnalysis.NotNullWhenAttribute jelzi a fordítónak, hogy a obj paraméterhez használt argumentum nem null értékű, amikor a metódus értékkel tér vissza. A metódus visszatérésekor falseaz argumentum null állapota megegyezik a metódus meghívása előtti null állapotával .

Tipp.

Számos attribútumot használhat a metódusok és tulajdonságok nullállapotra gyakorolt hatásának leírására. Ezekről a null értékű statikus elemzési attribútumokról szóló nyelvi referenciacikkben tájékozódhat.

A esetlegesen nullértékű változó dereferálására vonatkozó figyelmeztetés kijavítása három módszer egyikével történik:

  • Hiányzó null értékű ellenőrzés hozzáadása.
  • Adjon hozzá nullállapot-elemzési attribútumokat az API-khoz, hogy befolyásolja a fordító statikus elemzését. Ezek az attribútumok tájékoztatják a fordítót, ha a metódus meghívása után egy visszatérési értéknek vagy argumentumnak talán null vagy nem null értékűnek kell lennie.
  • Alkalmazza a nullelnéző operátort ! arra a kifejezésre, amely az állapotot not-null kényszeríti.

Lehetséges null érték hozzárendelve nem nullálható hivatkozáshoz

Ez a figyelmeztetési készlet értesíti, hogy olyan változót rendel hozzá, amely típusa nem-null, egy olyan kifejezéshez, amelynek null-állapotalehet, hogy null. Ezek a figyelmeztetések a következők:

  • A CS8597 - Kidobott érték null értékű lehet.
  • CS8600 - Null literál vagy lehetséges null érték konvertálása nem null értékű típusra.
  • CS8601 - Lehetséges nullhivatkozás-hozzárendelés.
  • CS8603 - Lehetséges null referencia visszatérés.
  • CS8604 - Lehetséges nullhivatkozás-érték argumentum paraméterhez.
  • CS8605 - Lehetséges null érték kicsomagolása.
  • CS8625 - A null literál nem konvertálható nem null értékű hivatkozástípussá.
  • A CS8629 - Nullable értéktípus null értékű lehet.

A fordító akkor bocsátja ki ezeket a figyelmeztetéseket, ha egy esetleg null értékű kifejezést próbál hozzárendelni egy nem-null értéket felvevő változóhoz. Példa:

string? TryGetMessage(int id) => "";

string msg = TryGetMessage(42);  // Possible null assignment.

A különböző figyelmeztetések a kód részleteit jelzik, például a hozzárendelést, a hozzárendelés feloldását, a visszatérési utasításokat, a metódusok argumentumait és a kifejezéseket.

Három művelet közül egyet végezhet el a figyelmeztetések kezelésére. Az egyik lehetőség, hogy hozzáadja a ? széljegyzetet, hogy a változó null értékeket is elfogadó hivatkozástípussá legyen. Ez a módosítás más figyelmeztetéseket is okozhat. Ha egy változót nem null értékű hivatkozásról null értékű hivatkozásra módosít, az alapértelmezett null-állapotot a not-nullróla talán-null értékre módosítja. A fordító statikus elemzése megkeresi azokat a példányokat, ahol egy változót talán null.

A többi művelet arra utasítja a fordítót, hogy a hozzárendelés jobb oldala ne null értékű legyen. A jobb oldali kifejezés a hozzárendelés előtt null értékű lehet, ahogy az alábbi példában látható:

string notNullMsg = TryGetMessage(42) ?? "Unknown message id: 42";

Az előző példák egy metódus visszatérési értékének hozzárendelését mutatják be. A metódust (vagy tulajdonságot) jegyzetekkel jelezheti, ha egy metódus nem null értéket ad vissza. A System.Diagnostics.CodeAnalysis.NotNullIfNotNullAttribute függvény gyakran azt határozza meg, hogy a visszatérési érték nem null értékű, ha egy bemeneti argumentum nem null értékű. Egy másik lehetőség a null felmentő operátor ! hozzáadása a jobb oldalra.

string msg = TryGetMessage(42)!;

A nem null változóhoz rendelhető talán null értékű kifejezésekre vonatkozó figyelmeztetés kijavítása négy módszer egyikét foglalja magában:

  • Módosítsa a hozzárendelés bal oldalát null értékű típusra. Ez a művelet új figyelmeztetéseket adhat meg a változó elhalasztásakor.
  • Végezzen null-ellenőrzést a hozzárendelés előtt.
  • Jelölje meg azt az API-t, amely a hozzárendelés jobb oldalát hozza létre.
  • Adja hozzá a null-megbocsátó operátort a hozzárendelés jobb oldalára.

Null értéket nem vevő hivatkozás nincs inicializálva

Ez a figyelmeztetési csoport figyelmezteti, hogy olyan változót rendel hozzá, amelynek típusa nem null értékű egy olyan kifejezéshez, amelynek null állapotalehet null. Ezek a figyelmeztetések a következők:

  • A CS8618 - Nem null értékű változónak nem null értéket kell tartalmaznia a konstruktorból való kilépéskor. Fontolja meg a null értékű deklarálást.
  • A CS8762 - paraméternek nem null értékűnek kell lennie kilépéskor.

Vegyük példaként a következő osztályt:

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

Sem FirstName, sem LastName inicializálása nincs garantálva. Ha ez a kód új, fontolja meg a nyilvános felület módosítását. Az előző példa a következőképpen frissíthető:

public class Person
{
    public Person(string first, string last)
    {
        FirstName = first;
        LastName = last;
    }

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

Ha a név megadása előtt létre kell hoznia egy Person objektumot, inicializálhatja a tulajdonságokat egy alapértelmezett nem null érték használatával:

public class Person
{
    public string FirstName { get; set; } = string.Empty;
    public string LastName { get; set; } = string.Empty;
}

Egy másik lehetőség, hogy null értékű hivatkozástípusokra módosítja ezeket a tagokat. Az Person osztályt a következőképpen lehet definiálni, ha a null engedélyezhető a névhez:

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

A meglévő kód néha más módosításokat is igényel ahhoz, hogy tájékoztassa a fordítót a tagok null szemantikáról. Több konstruktor is lehet benne, és az osztály egy vagy több tagot inicializáló privát segédmetódussal rendelkezik. Az inicializálási kódot egyetlen konstruktorba helyezheti át, és biztosíthatja, hogy minden konstruktor meghívja a közös inicializálási kóddal rendelkezőt. Vagy használhatja a System.Diagnostics.CodeAnalysis.MemberNotNullAttribute és a System.Diagnostics.CodeAnalysis.MemberNotNullWhenAttribute attribútumokat. Ezek az attribútumok tájékoztatják a fordítót, hogy egy tag nem null a metódus visszatérése után. 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";
    }
}

Végül a null engedő operátorral jelezheti, hogy egy tag inicializálva van a kód más részében. Egy másik példában vegye figyelembe az Entity Framework Core-modellt képviselő alábbi osztályokat:

public class TodoItem
{
    public long Id { get; set; }
    public string? Name { get; set; }
    public bool IsComplete { get; set; }
}

public class TodoContext : DbContext
{
    public TodoContext(DbContextOptions<TodoContext> options)
        : base(options)
    {
    }

    public DbSet<TodoItem> TodoItems { get; set; } = null!;
}

A DbSet tulajdonság inicializálása a következőre történik null!: . Ez azt jelzi a fordítónak, hogy a tulajdonság értéke nem null értékű. Valójában az alap DbContext végrehajtja a készlet inicializálását. A fordító statikus elemzése nem veszi ezt fel. A null értékű referenciatípusok és az Entity Framework Core használatával kapcsolatos további információkért tekintse meg a null értékű referenciatípusok EF Core-ban való használatát ismertető cikket.

Nem null értékű tag inicializálásával kapcsolatos figyelmeztetés kijavítása a következő négy módszer egyikével történhet:

  • Módosítsa a konstruktorokat vagy a mező inicializálóit, hogy minden nemnullálható tag inicializálva legyen.
  • Módosítsa egy vagy több tagot null értékű típusra.
  • Jegyezze fel a segédmetódusokat úgy, hogy jelezze, mely tagok vannak hozzárendelve.
  • Adjon hozzá egy inicializálót null! , amely jelzi, hogy a tag inicializálva van más kódban.

Érvénytelenségi deklaráció eltérése

Számos figyelmeztetés arra figyelmeztet, hogy a metódusok, delegáltak vagy típusparaméterek aláírásai között nullázhatósági eltérések vannak.

  • CS8608 - A típusban lévő referenciatípusok nullíthatósága nem egyezik a felülírt taggal.
  • CS8609 - A visszatérési típusban a hivatkozástípusok nullázhatósága nem egyezik meg a felülírt taggal.
  • A cs8610 - hivatkozástípusok érvénytelensége a típusparaméterben nem egyezik meg a felülírt tagokkal.
  • A típusparaméterben lévő referenciatípusok CS8611-es - érvénytelensége nem egyezik a részleges metódusdeklarációval.
  • CS8612 - A referenciatípusok nullázhatósága a típusban nem egyezik az implicit módon implementált taggal.
  • CS8613 - A visszatérési típus hivatkozástípusának anulálhatósága nem egyezik az implicit módon megvalósított tagéval.
  • CS8614 - A paraméter típusának hivatkozástípusú nullabilitása nem egyezik az implicit módon implementált taggal.
  • CS8615 - A referenciatípusok nullázhatósága a típusban nem egyezik az implementált taggal.
  • CS8616 - A visszatérési típusban lévő referenciatípusok nullázhatósága nem felel meg az implementált taggal.
  • CS8617 - A hivatkozástípusok nullabilitása a paraméter típusában nem egyezik a megvalósított taggal.
  • CS8619 referencia-típusok nullabilitása - nem egyezik a céltípus nullabilitásával.
  • A CS8620 - argumentum nem használható paraméterként a hivatkozástípusok nullázhatóságának különbségei miatt.
  • CS8621 - A visszatérési típusban lévő referenciatípusok null értékek kezelése nem egyezik meg a cél delegált null értékek kezelésével (esetleg azért, mert a null értékek kezelését jelző attribútumok nem felelnek meg).
  • A referenciatípusok CS8622 - paraméter típusában való nullabilitása nem felel meg a céldelegált nullabilitásának (esetleg a nullabilitási attribútumok miatt).
  • A CS8624 - argumentum nem használható kimenetként a hivatkozástípusok nullbilitásának különbségei miatt.
  • CS8631 - A típus nem használható típusparaméterként az általános típusban vagy metódusban. A típusargumentum érvénytelensége nem egyezik meg a kényszer típusával.
  • A CS8633 - a metódus típusparaméterének kényszerei nem egyeznek meg az interfészmetódus típusparamétereinek korlátozásaival. Fontolja meg inkább egy explicit interfész implementáció használatát.
  • CS8634 - A típus nem használható típusparaméterként az általános típusban vagy metódusban. A típusargumentum nullabilitása nem egyezik meg az "osztály" kényszerével.
  • CS8643: - A referenciatípusok nullabilitása az explicit interfészmeghatározóban nem egyezik a típus által implementált interfésszel.
  • A CS8644 - típus nem implementálja az interfész tagot. Az alaptípus által implementált interfészben lévő referenciatípusok nullválósága nem egyezik meg.
  • A CS8645 - Tag már szerepel az interfészlistában a hivatkozástípusok különböző null értékű típusára vonatkozóan.
  • A CS8667 - részleges metódus deklarációi inkonzisztens nullhipotenciával rendelkeznek a típusparaméter korlátaiban.
  • CS8714 - A típus nem használható típusparaméterként az általános típusban vagy metódusban. A típusargumentum nullabilitása nem egyezik a "notnull" kényszerével.
  • A CS8764 - visszatérési típus nullabilitása nem egyezik a felülírt tagéval (valószínűleg nullabilitási attribútumok miatt).
  • A CS8765 - paraméter típusának nullabilitása nem egyezik meg a felülírt tag típusával (valószínűleg nullabilitási attribútumok miatt).
  • A CS8766-os hivatkozástípusok nullabilitása - a visszatérési típusban nem egyezik az implicit módon implementált tagéval (valószínűleg a nullabilitási attribútumok miatt).
  • CS8767 kód: - A paraméter hivatkozási típusának nullabilitása nem egyezik az implicit módon implementált tag nullabilitásával (esetleg a nullabilitás attribútumok miatt).
  • CS8768 - A visszatérési típusban lévő referenciatípusok nullázhatósága nem egyezik az implementált tagéval (valószínűleg a nullázhatósági attribútumok miatt).
  • A paraméter típusa szerinti referenciatípusok nullázhatósága nem egyezik az implementált tagéval (esetleg a nullattribútumok miatt). CS8769
  • CS8819 - A visszatérési típus referenciatípusainak null-ellenőrzése nem egyezik a részleges metódus deklarációjával.

Az alábbi kód a CS8764-et mutatja be:

public class B
{
    public virtual string GetMessage(string id) => string.Empty;
}
public class D : B
{
    public override string? GetMessage(string? id) => default;
}

Az előző példa egy virtual alaposztályban lévő metódust és egy eltérő nullértékű metódust override mutat be. Az alaposztály nem null értékű sztringet ad vissza, a származtatott osztály viszont null értékű karakterláncot ad vissza. Ha az string és string? fel vannak cserélve, az megengedett, mert a leszármaztatott osztály szigorúbb. Hasonlóképpen, a paraméterdeklarációknak egyeznie kell. A felülbírálási metódus paraméterei akkor is engedélyezhetik a null értéket, ha az alaposztály nem.

Más helyzetek is létrehozhatják ezeket a figyelmeztetéseket. Az illesztőmetódus deklarációjában és a metódus implementálásában eltérés van. Vagy a delegált típusa és a delegált kifejezése eltér. A típusparaméter és a típusargumentum nullabilitásban különbözik.

A figyelmeztetések kijavításához frissítse a megfelelő deklarációt.

A kód nem egyezik az attribútumdeklarációval

Az előző szakaszokban bemutattuk, hogyan használhatók a Attribútumok a null értékű statikus elemzéshez szükséges arra, hogy tájékoztassa a fordítót a kód null szemantikájáról. A fordító figyelmezteti, ha a kód nem felel meg az attribútum ígéreteinek:

  • CS8607 - Olyan típushoz, amely [NotNull] vagy [DisallowNull] van megjelölve, lehetséges null érték nem használható.
  • CS8763 - A megjelölt [DoesNotReturn] metódus nem térhet vissza.
  • A CS8770 - metódus nem rendelkezik a implementált vagy felülbírált tagnak megfelelő széljegyzetekkel[DoesNotReturn].
  • A CS8774-tagnak - nem null értékűnek kell lennie kilépéskor.
  • A CS8775-tagnak - nem null értékűnek kell lennie kilépéskor.
  • CS8776 - Tag nem használható ebben az attribútumban.
  • A CS8777 - paraméternek nem null értékűnek kell lennie kilépéskor.
  • A CS8824 - paraméternek nem null értékűnek kell lennie a kilépéskor, mert a paraméter nem null.
  • A CS8825 - Visszatérési értéknek nem null értékűnek kell lennie, mert a paraméter nem null.

Fontolja meg a következő módszert:

public bool TryGetMessage(int id, [NotNullWhen(true)] out string? message)
{
    message = null;
    return true;

}

A fordító figyelmeztetést ad, mert a message paraméterhez hozzá van rendelve null, és a metódus visszaadja a true. Az NotNullWhen attribútum azt jelzi, hogy nem szabad megtörténnie.

A figyelmeztetések kezeléséhez frissítse a kódot úgy, hogy az megfeleljen az alkalmazott attribútumok elvárásainak. Módosíthatja az attribútumokat vagy az algoritmust.

Teljes kapcsolókifejezés

A kapcsolókifejezéseknek teljesnek kell lenniük, ami azt jelenti, hogy minden bemeneti értéket kezelni kell. Még a nem null értékű referenciatípusok esetében is figyelembe kell venni az null értéket. A fordító figyelmeztetéseket ad ki, ha a null értéket nem kezeli a rendszer:

  • CS8655 - A kapcsolókifejezés nem kezel null bemeneteket (nem teljes).
  • CS8847 - A kapcsolókifejezés nem kezel null bemeneteket (nem teljes). A "mikor" záradékkal rendelkező minta azonban sikeresen megfelelhet ennek az értéknek.

Az alábbi példakód ezt a feltételt mutatja be:

int AsScale(string status) =>
    status switch
    {
        "Red" => 0,
        "Yellow" => 5,
        "Green" => 10,
        { } => -1
    };

Az input kifejezés egy string, nem pedig egy string?. A fordító továbbra is létrehozza ezt a figyelmeztetést. A { } minta az összes nem null értéket kezeli, de nem egyezik meg null-vel. A hibák elhárításához hozzáadhat egy explicit null esetet, vagy lecserélheti a { } elemet a _ (elvetési) mintára. Az elvetési minta minden más érték mellett null értékű.