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


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.

A null értékű hivatkozástípusok olyan kódban érhetők el, amely null értékű tudatában. 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örnyezetek a projekt szintjén, buildbeállítások használatával vagy pragmák használatával kódban vezérelhetők.

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:

  • A hivatkozási típusú T változót nem null értékkel kell inicializálni, és soha nem rendelhető hozzá olyan érték, amely nulllehet.
  • A referencia típusú T? változó inicializálható null-gyel vagy hozzárendelhető null-höz, de dereferálás előtt ellenőrizni kell null-val.
  • A null-elbocsátó operátor alkalmazásakor a típusváltozó mT? nem null értékűnek minősül, ahogyan az a .m!

A fordító az előző szabályok alkalmazásával különbséget tesz a nem nullázható hivatkozástípus T és a nullázható hivatkozástípus T? között. 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őt a String típus jelöli. Mivel a nem null értékű és a null értékű típusok is ugyanabban a típusban vannak tárolva, több helyen nem engedélyezett null értékű hivatkozástípus használata. A null értékű referenciatípus általában nem használható alaposztályként vagy implementált felületként. Null értékű hivatkozástípus nem használható objektumlétrehozási vagy típustesztelési kifejezésben. A null értékű hivatkozástípus nem lehet taghozzáférés-kifejezés típusa. 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ő futásidejű 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. A helyi változókat oda kell hozzárendelni, ahol deklarálva vannak. 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 halasztá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.

A null hivatkozástípusok inicializálhatók vagy hozzárendelhetők null-hoz. Ezért a statikus elemzésnek meg kell állapítania, hogy egy változó nem null értékű a dereferencia előtt. Ha a null értékű hivatkozás talán null értékű, a nem null értékű referenciaváltozóhoz való hozzárendelés 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. Az API-khoz olyan attribútumok is hozzáadhatók, amelyek tájékoztatják 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 hozzáadhatja a projektbeállítást <Nullable>enable</Nullable> . Egyetlen C#-forrásfájlban hozzáadhatja 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ípusok szakaszát:

Lásd még