Odkazové typy s možnou hodnotou null

V nezapomnělém kontextu s možnou hodnotou null byly všechny odkazové typy null. Odkazové typy s možnou hodnotou null odkazují na skupinu funkcí povolených v kontextu s možnou hodnotou null, která minimalizuje pravděpodobnost, že váš kód způsobí vyvolání System.NullReferenceExceptionmodulu runtime . Odkazové typy s možnou hodnotou null zahrnují tři funkce, které vám pomohou vyhnout se těmto výjimkám, včetně možnosti explicitně označit typ odkazu jako nullable:

  • Vylepšená statická analýza toku, která určuje, jestli může být null proměnná před jeho odvozováním.
  • Atributy, které anotují rozhraní API tak, aby analýza toku určila stav null.
  • Poznámky k proměnným, které vývojáři používají k explicitní deklaraci zamýšleného stavu null pro proměnnou.

Kompilátor sleduje stav null každého výrazu v kódu v době kompilace. Stav null má jednu ze tří hodnot:

  • not-null: Výraz není-null.
  • možná-null: Výraz může být null.
  • Oblivious: Kompilátor nemůže určit stav null výrazu.

Poznámky k proměnným určují nulovou hodnotu proměnné typu odkazu:

  • non-nullable: Pokud proměnné přiřadíte null hodnotu nebo výraz možná null , kompilátor vydá upozornění. Proměnné, které nemají hodnotu null , mají výchozí stav null not-null.
  • nullable: Proměnné můžete přiřadit null hodnotu nebo výraz možná null . Pokud má proměnná hodnotu null-state je možná-null, kompilátor vydá upozornění, pokud proměnnou přeložíte. Výchozí stav null pro proměnnou je možná null.
  • obživitel: Proměnné můžete přiřadit null hodnotu nebo výraz s hodnotou null . Kompilátor neřeší upozornění, když proměnnou přeložíte, nebo když proměnné přiřadíte výraz s možnou hodnotou null .

Zapomnělý stav null a obživanost null se shodují s chováním před uvedením typů odkazů s možnou hodnotou null. Tyto hodnoty jsou užitečné během migrace nebo když vaše aplikace používá knihovnu, která nepovolila odkazové typy s možnou hodnotou null.

Analýza stavu null a poznámky proměnných jsou ve výchozím nastavení pro existující projekty zakázány – to znamená, že všechny odkazové typy budou nadále s možnou hodnotou null. Počínaje rozhraním .NET 6 jsou ve výchozím nastavení povolené pro nové projekty. Informace o povolení těchto funkcí deklarací kontextu poznámek s možnou hodnotou null naleznete v tématu Kontexty s možnou hodnotou Null.

Zbytek tohoto článku popisuje, jak tyto tři oblasti funkcí fungují, aby se zobrazila upozornění, když váš kód může hodnotu odvoditnull. Dereferencing proměnné znamená přístup k jednomu ze svých členů pomocí operátoru . (tečka), jak je znázorněno v následujícím příkladu:

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

Při dereference proměnné, jejíž hodnota je null, modul runtime vyvolá System.NullReferenceExceptionvýjimku .

Dozvíte se o:

  • Analýza stavu null kompilátoru: jak kompilátor určuje, jestli výraz není null nebo možná null.
  • Atributy, které se použijí na rozhraní API, které poskytují další kontext pro analýzu stavu null kompilátoru
  • Poznámky proměnné s možnou hodnotou null, které poskytují informace o záměru proměnných. Poznámky jsou užitečné pro pole k nastavení výchozího stavu null na začátku členských metod.
  • Pravidla, která řídí argumenty obecného typu. Byla přidána nová omezení, protože parametry typu mohou být odkazové typy nebo typy hodnot. Přípona ? je implementována odlišně pro typy hodnot s možnou hodnotou null a odkazové typy s možnou hodnotou null.
  • Kontexty s možnou hodnotou null vám pomůžou migrovat velké projekty. Při migraci můžete povolit kontexty s možnou hodnotou null nebo upozornění v částech aplikace. Po vyřešení dalších upozornění můžete povolit odkazové typy s možnou hodnotou null pro celý projekt.

Nakonec zjistíte známé nástrahy analýzy stavu null v struct typech a polích.

Tyto koncepty můžete prozkoumat také v našem modulu Learn o bezpečnosti s možnou hodnotou Null v jazyce C#.

Analýza stavu null

Pokud jsou povoleny odkazové typy s možnou hodnotou null, analýza stavu null sleduje stav null odkazů. Výraz buď není null, nebo možná null. Kompilátor určuje, že proměnná není null dvěma způsoby:

  1. Proměnná má přiřazenou hodnotu, o které je známo, že není null.
  2. Proměnná byla zkontrolována null a od této kontroly nebyla změněna.

Pokud nejsou povoleny odkazové typy s možnou hodnotou null, všechny výrazy mají stav hodnoty null nepochybné. Zbývající část popisuje chování při povolení typů odkazů s možnou hodnotou null.

Jakákoli proměnná, kterou kompilátor neurčí jako not-null , se považuje za možnou hodnotu null. Analýza poskytuje upozornění v situacích, kdy byste mohli omylem odvodit null hodnotu. Kompilátor generuje upozornění na základě stavu null.

  • Pokud proměnná není null, může být tato proměnná bezpečně odvozována.
  • Pokud je proměnná možná null, musí být tato proměnná kontrolována, aby se zajistilo, že není null před jeho odvozováním.

Představte si následující příklad:

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);

V předchozím příkladu kompilátor určuje, že message při tisku první zprávy je možná null . U druhé zprávy není žádné upozornění. Poslední řádek kódu vytvoří upozornění, protože originalMessage může mít hodnotu null. Následující příklad ukazuje praktičtější použití při procházení stromu uzlů do kořenového adresáře a zpracování jednotlivých uzlů během procházení:

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

Předchozí kód nevygeneruje žádná upozornění pro dereferencování proměnné current. Statická analýza určuje, že current se nikdy nezhoršuje, když je to možná null. Proměnná current se kontroluje před nullcurrent.Parent přístupem a před předáním currentProcessNode akce. Předchozí příklady ukazují, jak kompilátor určuje stav null pro místní proměnné při inicializaci, přiřazení nebo porovnání s null.

Analýza stavu null neprovádí trasování do volaných metod. Výsledkem je, že pole inicializovaná v běžné pomocné metodě volané všemi konstruktory vygenerují upozornění s následující šablonou:

Při ukončení konstruktoru musí vlastnost name obsahovat nenulovou hodnotu.

Tato upozornění můžete řešit jedním ze dvou způsobů: řetězení konstruktoru nebo atributy s možnou hodnotou null v pomocné metodě. Následující kód ukazuje příklad každého z nich. Třída Person používá společný konstruktor volaný všemi ostatními konstruktory. Třída Student má pomocnou metodu anotovanou atributem System.Diagnostics.CodeAnalysis.MemberNotNullAttribute :


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";
    }
}

Poznámka:

V jazyce C# 10 bylo přidáno několik vylepšení určitého přiřazení a analýzy stavu null. Při upgradu na C# 10 můžete najít méně upozornění s možnou hodnotou null, která jsou falešně pozitivní. Další informace o vylepšeních specifikacefunkcích

Analýza stavu s možnou hodnotou null a upozornění, která kompilátor generuje, vám pomůže vyhnout se chybám programu dereferencováním null. Článek o řešení upozorněnísch

Atributy podpisů rozhraní API

Analýza stavu null potřebuje od vývojářů rady, aby porozuměli sémantice rozhraní API. Některá rozhraní API poskytují kontroly hodnot null a měly by změnit stav null proměnné z hodnoty null na hodnotu not-null. Jiná rozhraní API vrací výrazy, které nejsou null nebo možná null v závislosti na stavu null vstupních argumentů. Představte si například následující kód, který zobrazí zprávu velkými písmeny:

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

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

Na základě kontroly by každý vývojář považoval tento kód za bezpečný a neměl by generovat upozornění. Kompilátor však neví, že IsNull poskytuje kontrolu hodnoty null a vydává upozornění pro message.ToUpper() příkaz, přičemž zvažuje message , že se má jednat o proměnnou s možnou hodnotou null . Toto upozornění opravíte pomocí atributu NotNullWhen :

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

Tento atribut informuje kompilátor, že pokud IsNull vrátí false, parametr s není null. Kompilátor změní stavmessage null na hodnotu not-null uvnitř if (!IsNull(message)) {...} bloku. Nejsou vydána žádná upozornění.

Atributy poskytují podrobné informace o stavu null argumentů, návratové hodnoty a členy instance objektu použité k vyvolání členu. Podrobnosti o jednotlivých atributech najdete v článku s referenčními informacemi jazyka o atributech odkazu s možnou hodnotou null. Od verze .NET 5 jsou všechna rozhraní API modulu runtime .NET opatřena poznámkami. Statickou analýzu vylepšíte přidáním poznámek k rozhraním API za účelem poskytnutí sémantických informací o stavu null argumentů a návratových hodnotách.

Poznámky proměnných s možnou hodnotou null

Analýza stavu null poskytuje robustní analýzu místních proměnných. Kompilátor od vás potřebuje další informace pro členské proměnné. Kompilátor potřebuje další informace k nastavení stavu null všech polí v počáteční závorce člena. K inicializaci objektu lze použít kterýkoli z přístupných konstruktorů. Pokud by mohlo být pole člena nastaveno na null, kompilátor musí předpokládat, že jeho stav null je možná null na začátku každé metody.

Používáte poznámky, které mohou deklarovat, zda je proměnná typu odkazu s možnou hodnotou null nebo nenulový odkaz. Tyto poznámky dělají důležité prohlášení o stavu null pro proměnné:

  • Odkaz by neměl být null. Výchozí stav nenulové referenční proměnné není null. Kompilátor vynucuje pravidla, která zajišťují, že je bezpečné převést tyto proměnné bez první kontroly, že není null:
    • Proměnná musí být inicializována na hodnotu, která není null.
    • Proměnnou nelze nikdy přiřadit hodnotu null. Kompilátor vydá upozornění, když kód přiřadí výraz možná null proměnné, která by neměla mít hodnotu null.
  • Odkaz může mít hodnotu null. Výchozí stav referenční proměnné s možnou hodnotou null je možná null. Kompilátor vynucuje pravidla, která zajistí, že správně zkontrolujete null odkaz:
    • Proměnná může být dereference pouze tehdy, když kompilátor může zaručit, že hodnota není null.
    • Tyto proměnné mohou být inicializovány s výchozí null hodnotou a mohou být přiřazeny hodnotu null v jiném kódu.
    • Kompilátor nedává upozornění, když kód přiřadí výraz s možnou hodnotou null proměnné, která může mít hodnotu null.

Každá referenční proměnná bez hodnoty null má výchozí stavnull not-null. Každá referenční proměnná s možnou hodnotou null má počáteční stav null, který má hodnotu možná-null.

Typ odkazu s možnou hodnotou null je zaznamenán pomocí stejné syntaxe jako typy hodnot null: ? k typu proměnné se připojí. Například následující deklarace proměnné představuje proměnnou řetězce s možnou hodnotou null: name

string? name;

Pokud jsou povoleny odkazové typy s možnou hodnotou null, každá proměnná, která ? není připojena k názvu typu, je nenulový odkazový typ. To zahrnuje všechny proměnné typu odkazu v existujícím kódu, jakmile tuto funkci povolíte. Všechny implicitně zadané místní proměnné (deklarované pomocí var) jsou však odkazové typy s možnou hodnotou null. Jak ukázaly předchozí části, statická analýza určuje stav null místních proměnných, aby bylo možné určit, jestli jsou možná null před jeho dereferencací.

Někdy je nutné přepsat upozornění, když víte, že proměnná není null, ale kompilátor určí její stav null-null. Pomocí operátoru ! null-forgiving za názvem proměnné vynutíte, aby stav null nebyl null. Pokud například víte name , že proměnná není null , ale kompilátor vydá upozornění, můžete napsat následující kód, který přepíše analýzu kompilátoru:

name!.Length;

Odkazové typy s možnou hodnotou null a typy hodnot null poskytují podobný sémantický koncept: Proměnná může představovat hodnotu nebo objekt, nebo tato proměnná může být null. Odkazové typy s možnou hodnotou null a typy hodnot null jsou však implementovány odlišně: typy hodnot s možnou hodnotou null jsou implementovány pomocí System.Nullable<T>a typy odkazů s možnou hodnotou null jsou implementovány atributy přečtenými kompilátorem. Například string? oba string jsou reprezentovány stejným typem: System.String. int?int Jsou však reprezentovány System.Nullable<System.Int32> a System.Int32v uvedeném pořadí.

Odkazové typy s možnou hodnotou null jsou funkcí doby kompilace. To znamená, že volající může ignorovat upozornění, záměrně použít null jako argument metody, která očekává nenulový odkaz. Autoři knihoven by měli zahrnout kontroly za běhu s hodnotami argumentů null. Upřednostňovanou ArgumentNullException.ThrowIfNull možností je kontrola parametru proti hodnotě null za běhu.

Důležité

Povolení poznámeksch Další podrobnosti najdete v článku o základech Entity Framework Core: Práce s odkazovými typy s možnou hodnotou Null.

Obecné typy

Obecné typy vyžadují podrobná pravidla pro zpracování T? libovolného parametru Ttypu . Pravidla jsou nutně podrobná z důvodu historie a různé implementace pro typ hodnoty s možnou hodnotou null a typ odkazu s možnou hodnotou null. Typy hodnot s možnou System.Nullable<T> hodnotou null jsou implementovány pomocí struktury. Odkazové typy s možnou hodnotou null jsou implementovány jako poznámky typu, které kompilátoru poskytují sémantická pravidla.

  • Pokud je argument T typu typu odkaz, T? odkazuje na odpovídající typ odkazu s možnou hodnotou null. Pokud je například T , stringpak T? je .string?
  • Pokud je argument T typu pro typ hodnoty, T? odkazuje na stejný typ hodnoty . T Pokud je například T , intT? je to také int.
  • Pokud je argument T typu typu typu odkaz s možnou hodnotou null, T? odkazuje na stejný typ odkazu s možnou hodnotou null. Pokud je například T , string?pak T? je také string?.
  • Pokud je argument T typu pro typ T? hodnoty null, odkazuje na stejný typ hodnoty nullable. Pokud je například T , int?pak T? je také int?.

Pro návratové hodnoty T? je ekvivalentní [MaybeNull]Thodnotě ; pro hodnoty T? argumentu je ekvivalentní [AllowNull]T. Další informace najdete v článku o atributech pro analýzu stavu null v referenční dokumentaci jazyka.

Pomocí omezení můžete určit jiné chování:

  • Omezení class znamená, že T musí být nenulový odkazový typ (například string). Kompilátor vygeneruje upozornění, pokud použijete odkaz s možnou hodnotou null, například string? pro T.
  • Omezení class? znamená, že T musí být odkazovým typem, který nesmí být nullable (string) nebo typu odkazu s možnou hodnotou null (například string?). Pokud je parametr typu odkazem typu typu nullable, například string?výraz T? odkazů, které mají stejný typ odkazu s možnou hodnotou null, například string?.
  • Omezení notnull znamená, že T musí být nenulový odkazový typ nebo nenulový typ hodnoty. Pokud pro parametr typu použijete odkaz s možnou hodnotou null nebo typ hodnoty null, kompilátor vygeneruje upozornění. Pokud je to T typ hodnoty, návratová hodnota je tento typ hodnoty, nikoli odpovídající typ hodnoty nullable.

Tato omezení pomáhají kompilátoru poskytnout další informace o tom, jak T se používá. To pomáhá, když vývojáři zvolí typ pro T a poskytují lepší analýzu stavu null, když se použije instance obecného typu.

Kontexty s možnou hodnotou null

U malých projektů můžete povolit odkazové typy s možnou hodnotou null, opravit upozornění a pokračovat. U větších projektů a řešení s více projekty ale může vygenerovat velký počet upozornění. Pragmas můžete použít k povolení typů odkazů s možnou hodnotou null, když začnete používat odkazové typy s možnou hodnotou null. Nové funkce, které chrání před vyvoláním System.NullReferenceException , můžou být při zapnutí v existujícím základu kódu rušivé:

  • Všechny explicitní odkazové proměnné jsou interpretovány jako odkazové typy bez hodnoty null.
  • Význam omezení vobecnýchch class
  • Kvůli těmto novým pravidlům se generují nová upozornění.

Kontext poznámek s možnou hodnotou null určuje chování kompilátoru. Kontext poznámek s možnou hodnotou null má čtyři hodnoty:

  • disable: Kód je nulový a nezapomnělý. Zakázat porovnává chování před povolenými odkazovými typy s možnou hodnotou null, s výjimkou nové syntaxe se místo chyb zobrazí upozornění.
    • Upozornění s možnou hodnotou null jsou zakázaná.
    • Všechny proměnné typu odkazu jsou odkazové typy s možnou hodnotou null.
    • Použití přípony ? k deklaraci typu odkazu s možnou hodnotou null vytvoří upozornění.
    • Můžete použít operátor pro odpouštění null, !ale nemá žádný vliv.
  • enable: Kompilátor povolí všechny referenční analýzy null a všechny jazykové funkce.
    • Jsou povolena všechna nová upozornění s možnou hodnotou null.
    • Příponu ? můžete použít k deklaraci typu odkazu s možnou hodnotou null.
    • Proměnné typu odkazu bez ? přípony jsou odkazové typy bez hodnoty null.
    • Operátor odpustit hodnotu null potlačí upozornění pro možné přiřazení .null
  • upozornění: Kompilátor provede veškerou analýzu null a vygeneruje upozornění, když může kód dereference null.
    • Jsou povolena všechna nová upozornění s možnou hodnotou null.
    • Použití přípony ? k deklaraci typu odkazu s možnou hodnotou null vytvoří upozornění.
    • Všechny proměnné typu odkazu mohou mít hodnotu null. Členové však mají stav null-nullna počáteční složené závorce všech metod, pokud nejsou deklarovány s příponou ? .
    • Můžete použít operátor pro odgiving, !.
  • poznámky: Kompilátor nevysílá upozornění, když kód může dereference nullnebo když přiřadíte výraz s hodnotou null proměnné, která nemá hodnotu null.
    • Všechna nová upozornění s možnou hodnotou null jsou zakázaná.
    • Příponu ? můžete použít k deklaraci typu odkazu s možnou hodnotou null.
    • Proměnné typu odkazu bez ? přípony jsou odkazové typy bez hodnoty null.
    • Můžete použít operátor pro odpouštění null, !ale nemá žádný vliv.

Kontext poznámek s možnou hodnotou null a kontext upozornění s možnou hodnotou null lze nastavit pro projekt pomocí elementu <Nullable> v souboru .csproj. Tento element konfiguruje, jak kompilátor interpretuje hodnotu nullability typů a jaká upozornění se vygenerují. Následující tabulka ukazuje povolené hodnoty a shrnuje kontexty, které zadávají.

Kontext Upozornění na dereference Upozornění přiřazení Typy odkazů ? Přípona ! Operátor
disable Disabled Disabled Všechny mají možnou hodnotu null. Vytvoří upozornění. Nemá žádný vliv
enable Povolený Povolený Bez hodnoty null, pokud není deklarováno ? Deklaruje typ s možnou hodnotou null. Potlačí upozornění pro možné null přiřazení.
warnings Povoleno Nelze použít Všechny jsou nullable, ale členy jsou považovány za nenulové při otevření složené závorky metod. Vytvoří upozornění. Potlačí upozornění pro možné null přiřazení.
annotations Disabled Disabled Bez hodnoty null, pokud není deklarováno ? Deklaruje typ s možnou hodnotou null. Nemá žádný vliv

Proměnné typu odkazu v kódu zkompilované v zakázaném kontextu jsou neplatné. Literál nebo proměnnou s možnou hodnotou null můžete přiřadit null proměnné, která je neslušná. Výchozí stav proměnné s možnou hodnotou null však není null.

Můžete zvolit, které nastavení je pro váš projekt nejvhodnější:

  • Zvolte zakázat starší projekty, které nechcete aktualizovat na základě diagnostiky nebo nových funkcí.
  • Zvolte upozornění a určete, kde může kód vyvolat System.NullReferenceException. Tato upozornění můžete vyřešit před úpravou kódu, abyste povolili odkazové typy bez hodnoty null.
  • Před povolením upozornění zvolte poznámky , které chcete vyjádřit záměr návrhu.
  • Zvolte povolit pro nové projekty a aktivní projekty, u kterých chcete chránit před výjimkami odkazu s hodnotou null.

Příklad:

<Nullable>enable</Nullable>

Direktivy můžete také použít k nastavení těchto stejných kontextů kdekoli ve zdrojovém kódu. Tyto direktivy jsou nejužitečnější při migraci velkého základu kódu.

  • #nullable enable: Nastaví kontext poznámek s možnou hodnotou null a kontext upozornění s možnou hodnotou null, aby se povolil.
  • #nullable disable: Nastaví kontext poznámek s možnou hodnotou null a kontext upozornění s možnou hodnotou null, aby se zakázal.
  • #nullable restore: Obnoví kontext poznámek s možnou hodnotou null a kontext upozornění s možnou hodnotou null do nastavení projektu.
  • #nullable disable warnings: Nastavte kontext upozornění s možnou hodnotou null, který chcete zakázat.
  • #nullable enable warnings: Nastavte kontext upozornění s možnou hodnotou null, který chcete povolit.
  • #nullable restore warnings: Obnoví kontext upozornění s možnou hodnotou null do nastavení projektu.
  • #nullable disable annotations: Nastavte kontext poznámek s možnou hodnotou null, který chcete zakázat.
  • #nullable enable annotations: Nastavte kontext poznámek s možnou hodnotou null, který chcete povolit.
  • #nullable restore annotations: Obnoví kontext upozornění poznámek do nastavení projektu.

Pro libovolný řádek kódu můžete nastavit některou z následujících kombinací:

Kontext upozornění Kontext poznámek Používání
Výchozí nastavení projektu Výchozí nastavení projektu Výchozí
Povolit disable Oprava upozornění analýzy
Povolit Výchozí nastavení projektu Oprava upozornění analýzy
Výchozí nastavení projektu Povolit Přidání poznámek k typu
Povolit Povolit Kód už migrovaný
disable Povolit Označení kódu poznámkami před opravou upozornění
disable disable Přidání staršího kódu do migrovaného projektu
Výchozí nastavení projektu disable Zřídka
disable Výchozí nastavení projektu Zřídka

Tyto devět kombinací poskytují jemně odstupňovanou kontrolu nad diagnostikou, kterou kompilátor generuje pro váš kód. V jakékoli oblasti, kterou aktualizujete, můžete povolit další funkce, aniž byste viděli další upozornění, která ještě nejste připravení řešit.

Důležité

Globální kontext s možnou hodnotou null se nevztahuje na vygenerované soubory kódu. V obou strategiích je kontext s možnou hodnotou null zakázán pro jakýkoli zdrojový soubor označený jako vygenerovaný. To znamená, že žádná rozhraní API ve vygenerovaných souborech nejsou opatřena poznámkami. Soubor je označený jako vygenerovaný čtyřmi způsoby:

  1. V souboru .editorconfig zadejte generated_code = true v oddílu, který se vztahuje na tento soubor.
  2. Umístěte <auto-generated> komentář do horní části souboru nebo <auto-generated/> do komentáře. Může být na libovolném řádku v daném komentáři, ale blok komentáře musí být prvním prvkem v souboru.
  3. Spusťte název souboru pomocí TemporaryGeneratedFile_
  4. Ukončete název souboru .designer.cs, .generated.cs, .g.cs nebo .g.i.cs.

Generátory se můžou přihlásit pomocí direktivy preprocesoru #nullable .

Ve výchozím nastavení jsou zakázané kontexty poznámek s možnou hodnotou null a upozornění. To znamená, že existující kód se zkompiluje beze změn a bez generování nových upozornění. Počínaje rozhraním .NET 6 zahrnují <Nullable>enable</Nullable> nové projekty prvek do všech šablon projektů.

Tyto možnosti poskytují dvě odlišné strategie aktualizace existujícího základu kódu tak, aby používaly odkazové typy s možnou hodnotou null.

Známé nástrahy

Pole a struktury, které obsahují odkazové typy, jsou známé nástrahy v odkazech s možnou hodnotou null a statická analýza, která určuje bezpečnost null. V obou situacích může být inicializován odkaz bez hodnoty null, aniž nullby se vygenerovaly upozornění.

Struktury

Struktura, která obsahuje nenulové odkazové typy, umožňuje přiřazení default bez upozornění. Představte si následující příklad:

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);
}

V předchozím příkladu neexistuje žádné upozornění PrintStudent(default) , zatímco odkazové typy FirstName bez hodnoty null a LastName mají hodnotu null.

Dalším běžným případem je, když se zabýváte obecnými strukturami. Představte si následující příklad:

#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;
    }
}

V předchozím příkladu je null vlastnost Prop za běhu. Je přiřazený k nenulovatelnému řetězci bez upozornění.

Pole

Pole jsou také známým nástrahám v odkazových typech s možnou hodnotou null. Podívejte se na následující příklad, který nevygeneruje žádná upozornění:

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());
    }
}

V předchozím příkladu deklarace pole ukazuje, že obsahuje nenulové řetězce, zatímco jeho prvky jsou všechny inicializovány na null. Potom je proměnná s přiřazena null hodnota (první prvek pole). Nakonec se proměnná s dereferenced způsobuje výjimku za běhu.

Viz také