Megosztás:


Null értékű hivatkozástípusok (C# hivatkozás)

Feljegyzés

Ez a cikk a null értékű hivatkozástípusokat ismerteti. Null értékű értéktípusokat is deklarálhat.

Null értékű hivatkozástípusokat is használhat a null értékű tudatában lévő kódban. A null értékű hivatkozástípusok, a null statikus elemzési figyelmeztetések és a null-megbocsátó operátor választható nyelvi funkciók. Alapértelmezés szerint minden ki van kapcsolva. A null értékű környezeteket a projekt szintjén a build beállításaival vagy kódban, pragmák használatával szabályozhatja.

A C# nyelv referenciadokumentuma a C# nyelv legújabb kiadású verzióját ismerteti. Emellett a közelgő nyelvi kiadás nyilvános előzetes verziójú funkcióinak kezdeti dokumentációját is tartalmazza.

A dokumentáció azonosítja azokat a funkciókat, amelyeket először a nyelv utolsó három verziójában vagy az aktuális nyilvános előzetes verziókban vezetnek be.

Jótanács

Ha meg szeretné tudni, hogy mikor jelent meg először egy funkció a C#-ban, tekintse meg a C# nyelvi verzióelőzményeiről szóló cikket.

Fontos

Minden projektsablon engedélyezi a projekt számára a nullázható kontextus-t. A korábbi sablonokkal létrehozott projektek nem tartalmazzák ezt az elemet, és ezek a funkciók ki vannak kapcsolva, hacsak nem engedélyezi őket a projektfájlban, vagy nem használja a pragmákat.

Null értékű tudatos környezetben:

  • Nem null értékű referencia típusú T változót kell inicializálnia, és soha nem rendelhet hozzá olyan értéket, amely lehet null.
  • Egy referenciatípusú T?null változót inicializálhat vagy hozzárendelhet null, de a halasztás előtt ellenőriznie null kell.
  • Ha a null-elbocsátó operátort egy típusú T?változóra m alkalmazza, a m!változó nem null értékűnek minősül.

A fordító az előző szabályok használatával kényszeríti ki a nem null értékű referenciatípus T és a null értékű referenciatípus T? közötti különbségeket. A T típusú változók és a T? típusú változók a .NET-típussal azonosak. Az alábbi példa egy nem null értékű sztringet és egy null értékű karakterláncot deklarál, majd a null-elbocsátó operátor használatával rendel egy értéket egy nem null értékű sztringhez:

string notNull = "Hello";
string? nullable = default;
notNull = nullable!; // null forgiveness

A változók notNull és nullable mindkettő a típust String használja. Mivel a nem null értékű és a null értékű típusok is ugyanazt a típust használják, több helyen nem használhat null értékű hivatkozástípust. Általában nem használhat null értékű hivatkozástípust alaposztályként vagy implementált felületként. Objektumlétrehozási vagy típustesztelési kifejezésben nem használhat null értékű hivatkozástípust. Taghozzáférés-kifejezés típusaként nem használhat null értékű hivatkozástípust. Az alábbi példák a következő szerkezeteket mutatják be:

public MyClass : System.Object? // not allowed
{
}

var nullEmpty = System.String?.Empty; // Not allowed
var maybeObject = new object?(); // Not allowed
try
{
    if (thing is string? nullableString) // not allowed
        Console.WriteLine(nullableString);
} catch (Exception? e) // Not Allowed
{
    Console.WriteLine("error");
}

Null értékű hivatkozások és statikus elemzés

Az előző szakaszban szereplő példák a null értékű hivatkozástípusok természetét szemléltetik. A null értékű hivatkozástípusok nem új osztálytípusok, hanem a meglévő referenciatípusokhoz tartozó széljegyzetek. A fordító ezeket a széljegyzeteket használva segít megtalálni a kódban esetleges nullhivatkozási hibákat. Nincs futásidejű különbség a nem null értékű referenciatípus és a null értékű referenciatípus között. A fordító nem ad hozzá futtatókörnyezet-ellenőrzést a nem null értékű referenciatípusokhoz. Az előnyök a fordítási idő elemzésében érhetők el. A fordító figyelmeztetéseket hoz létre, amelyek segítenek megtalálni és kijavítani a kód esetleges null hibáit. Deklarálja a szándékot, és a fordító figyelmezteti, ha a kód megsérti ezt a szándékot.

Fontos

A null értékű hivatkozási széljegyzetek nem vezetnek be viselkedésbeli változásokat, más kódtárak azonban a visszaverődést használva különböző futtatókörnyezeti viselkedést eredményezhetnek a null értékű és a nem null értékű referenciatípusokhoz. Az Entity Framework Core például null értékű attribútumokat olvas be. A null értékű hivatkozást opcionális értékként, a nem null értékű hivatkozást pedig kötelező értékként értelmezi.

Null értékű környezetben a fordító statikus elemzést végez bármilyen referenciatípusú változón, null értékű és nem null értékű változókon. A fordító az egyes referenciaváltozók null állapotát not-null vagy talán-null értékként követi nyomon. A nem null értékű hivatkozás alapértelmezett állapota nem null. A null értékű hivatkozás alapértelmezett állapota talán-null.

A nem null értékű hivatkozástípusoknak mindig biztonságosnak kell lenniük a hareferencia érdekében, mert null állapotuk nem null. A szabály kényszerítéséhez a fordító figyelmeztetéseket ad ki, ha egy nem null értékű hivatkozástípus nincs inicializálva nem null értékűre. Helyi változókat kell hozzárendelnie, ahol deklarálja őket. Minden mezőhöz nem null értéket kell hozzárendelni, egy mező inicializálójában vagy minden konstruktorban. A fordító figyelmeztetéseket ad ki, ha nem null értékű hivatkozás van hozzárendelve egy olyan hivatkozáshoz, amelynek az állapota talán null. A nem null értékű hivatkozások általában nem null értékűek , és nem jelennek meg figyelmeztetések a változók elhalasztásakor.

Feljegyzés

Ha nem null értékű hivatkozástípushoz rendel hozzá egy talán null értékű kifejezést, a fordító figyelmeztetést hoz létre. A fordító ezután figyelmeztetéseket hoz létre a változóhoz, amíg nem rendeli hozzá egy nem null értékű kifejezéshez.

Inicializálhatja vagy hozzárendelheti null a null értékű hivatkozástípusokat. Ezért a statikus elemzésnek meg kell állapítania, hogy egy változó nem null értékű a dereferencia előtt. Ha egy null értékű hivatkozás úgy van meghatározva, hogy talán null értékű, akkor a nem null értékű referenciaváltozóhoz való hozzárendelése fordítói figyelmeztetést eredményez. Az alábbi osztály példákat mutat be ezekre a figyelmeztetésekre:

public class ProductDescription
{
    private string shortDescription;
    private string? detailedDescription;

    public ProductDescription() // Warning! shortDescription not initialized.
    {
    }

    public ProductDescription(string productDescription) =>
        this.shortDescription = productDescription;

    public void SetDescriptions(string productDescription, string? details=null)
    {
        shortDescription = productDescription;
        detailedDescription = details;
    }

    public string GetDescription()
    {
        if (detailedDescription.Length == 0) // Warning! dereference possible null
        {
            return shortDescription;
        }
        else
        {
            return $"{shortDescription}\n{detailedDescription}";
        }
    }

    public string FullDescription()
    {
        if (detailedDescription == null)
        {
            return shortDescription;
        }
        else if (detailedDescription.Length > 0) // OK, detailedDescription can't be null.
        {
            return $"{shortDescription}\n{detailedDescription}";
        }
        return shortDescription;
    }
}

Az alábbi kódrészlet bemutatja, hogy a fordító hol bocsát ki figyelmeztetéseket az osztály használatakor:

string shortDescription = default; // Warning! non-nullable set to null;
var product = new ProductDescription(shortDescription); // Warning! static analysis knows shortDescription maybe null.

string description = "widget";
var item = new ProductDescription(description);

item.SetDescriptions(description, "These widgets will do everything.");

Az előző példák bemutatják, hogyan határozza meg a fordító statikus elemzése a referenciaváltozók nullállapotát . A fordító a null értékű ellenőrzésekre és hozzárendelésekre vonatkozó nyelvi szabályokat alkalmaz az elemzésének tájékoztatására. A fordító nem tud feltételezni a metódusok és tulajdonságok szemantikáját. Ha null értékű ellenőrzéseket végrehajtó metódusokat hív meg, a fordító nem tudja, hogy ezek a metódusok hatással vannak egy változó nullállapotára. Attribútumokat adhat az API-khoz, hogy tájékoztassa a fordítót az argumentumok szemantikáiról és az értékek visszaadásáról. A .NET-kódtárakban számos gyakori API rendelkezik ezekkel az attribútumokkal. A fordító például helyesen értelmezi a IsNullOrEmpty null értékű ellenőrzésként. A null állapotú statikus elemzésre alkalmazott attribútumokról további információt a Null értékű attribútumokról szóló cikkben talál.

A null értékű környezet beállítása

A null értékű környezet kétféleképpen szabályozható. A projekt szintjén adja hozzá a projektbeállítást <Nullable>enable</Nullable> . Egyetlen C#-forrásfájlban adja hozzá a #nullable enable pragmát a null értékű környezet engedélyezéséhez. Tekintse meg a null értékű stratégia beállításáról szóló cikket. A .NET 6 előtt az új projektek az alapértelmezettet használják, <Nullable>disable</Nullable>. A .NET 6-tól kezdődően az új projektek tartalmazzák a <Nullable>enable</Nullable> projektfájl elemét.

C# nyelvspecifikáció

További információkért tekintse meg a C# nyelvspecifikációNullable referenciatípusokkal foglalkozó szakaszát.

Lásd még