Null-verwijzingstypen

In een context die niet kan worden vergeten, waren alle verwijzingstypen nullbaar. Nullable-verwijzingstypen verwijzen naar een groep functies die zijn ingeschakeld in een context die nullable is ingeschakeld, waardoor de kans dat uw code ervoor zorgt dat de runtime wordt veroorzaakt, wordt geminimaliseerd System.NullReferenceException. Null-verwijzingstypen bevatten drie functies waarmee u deze uitzonderingen kunt voorkomen, waaronder de mogelijkheid om expliciet een verwijzingstype als null-type te markeren:

  • Verbeterde statische stroomanalyse die bepaalt of een variabele mogelijk is null voordat deze wordt uitgesteld.
  • Kenmerken waarmee aantekeningen worden toegevoegd aan API's, zodat de stroomanalyse de null-status bepaalt.
  • Variabeleaantekeningen die ontwikkelaars gebruiken om expliciet de beoogde null-status voor een variabele te declareren.

De compiler houdt de null-status van elke expressie in uw code bij tijdens het compileren. De null-status heeft een van de drie waarden:

  • not-null: de expressie is bekend dat deze nietnull is.
  • misschien-null: de expressie kan zijn null.
  • vergetelheid: de compiler kan de null-status van de expressie niet bepalen.

Variabeleaantekeningen bepalen de null-waarde van een variabele van het verwijzingstype:

  • niet nullable: als u een null waarde of een misschien null-expressie aan de variabele toewijst, geeft de compiler een waarschuwing. Variabelen die niet null kunnen worden gebruikt, hebben een standaard null-status van not-null.
  • nullable: u kunt een null waarde of een misschien-null-expressie toewijzen aan de variabele. Wanneer de null-status van de variabele mogelijk null is, geeft de compiler een waarschuwing als u de variabele deductie geeft. De standaard null-status voor de variabele is misschien null.
  • vergetelheid: u kunt een null waarde of een misschien null-expressie toewijzen aan de variabele. De compiler geeft geen waarschuwingen uit wanneer u de variabele deducteert of wanneer u een mogelijk null-expressie aan de variabele toewijst.

De vergetele null-status en de vergetelheid van de null-waarde komen overeen met het gedrag voordat null-referentietypen werden geïntroduceerd. Deze waarden zijn handig tijdens de migratie of wanneer uw app gebruikmaakt van een bibliotheek waarvoor geen nullable referentietypen zijn ingeschakeld.

Analyse van null-status en variabeleaantekeningen zijn standaard uitgeschakeld voor bestaande projecten. Dit betekent dat alle verwijzingstypen null kunnen blijven. Vanaf .NET 6 worden ze standaard ingeschakeld voor nieuwe projecten. Zie Null-contexten voor informatie over het inschakelen van deze functies door een nullable annotatiecontext te declareren.

In de rest van dit artikel wordt beschreven hoe deze drie functiegebieden werken om waarschuwingen te produceren wanneer uw code een null waarde mogelijk uitstellen. Het uitstellen van een variabele betekent toegang tot een van de leden met behulp van de . operator (dot), zoals wordt weergegeven in het volgende voorbeeld:

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

Wanneer u een variabele deductie maakt waarvan de waarde is null, genereert de runtime een System.NullReferenceException.

U krijgt meer informatie over:

  • De analyse van de null-status van de compiler: hoe de compiler bepaalt of een expressie niet null is of misschien null.
  • Kenmerken die worden toegepast op API's die meer context bieden voor de null-statusanalyse van de compiler.
  • Aantekeningen voor null-variabelen die informatie bevatten over uw intentie voor variabelen. Aantekeningen zijn handig voor velden om de standaard null-status in te stellen aan het begin van de lidmethoden.
  • De regels voor algemene typeargumenten. Er zijn nieuwe beperkingen toegevoegd omdat typeparameters verwijzingstypen of waardetypen kunnen zijn. Het ? achtervoegsel wordt anders geïmplementeerd voor typen null-waarden en null-verwijzingstypen.
  • Met null-contexten kunt u grote projecten migreren. U kunt null-contexten of waarschuwingen inschakelen in delen van uw app terwijl u migreert. Nadat u meer waarschuwingen hebt adresseert, kunt u null-referentietypen voor het hele project inschakelen.

Ten slotte leert u bekende valkuilen voor null-statusanalyse in struct typen en matrices.

U kunt deze concepten ook verkennen in onze Learn-module over nullable veiligheid in C#.

analyse van null-status

Wanneer null-verwijzingstypen zijn ingeschakeld, wordt met null-statusanalyse de null-status van verwijzingen bijgehouden. Een expressie is niet null of misschien null. De compiler bepaalt dat een variabele niet null is op twee manieren:

  1. Aan de variabele is een waarde toegewezen die niet null is.
  2. De variabele is gecontroleerd tegen null en is niet gewijzigd sinds die controle.

Wanneer nullable-verwijzingstypen niet zijn ingeschakeld, hebben alle expressies de null-status van vergetelheid. In de rest van de sectie wordt het gedrag beschreven wanneer null-verwijzingstypen zijn ingeschakeld.

Elke variabele die de compiler niet heeft bepaald als not-null, wordt beschouwd als misschien-null. De analyse biedt waarschuwingen in situaties waarin u per ongeluk een null waarde kunt deductie uitvoeren. De compiler produceert waarschuwingen op basis van de null-status.

  • Wanneer een variabele niet null is, kan deze variabele veilig worden gededucteerd.
  • Wanneer een variabele misschien null is, moet die variabele worden gecontroleerd om ervoor te zorgen dat deze niet null wordt uitgesteld voordat deze wordt uitgesteld.

Kijk een naar het volgende voorbeeld:

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

In het voorgaande voorbeeld bepaalt de compiler dat message het misschien null is wanneer het eerste bericht wordt afgedrukt. Er is geen waarschuwing voor het tweede bericht. De laatste regel code produceert een waarschuwing omdat originalMessage deze mogelijk null is. In het volgende voorbeeld ziet u een praktischer gebruik voor het doorkruisen van een structuur van knooppunten naar de hoofdmap, waarbij elk knooppunt tijdens de doorkruising wordt verwerkt:

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

De vorige code genereert geen waarschuwingen voor het uitstellen van de variabele current. Statische analyse bepaalt dat deze current nooit wordt gededucteerd wanneer het misschien null is. De variabele current wordt gecontroleerd op null voordat current.Parent deze wordt geopend en voordat deze wordt doorgegeven current aan de ProcessNode actie. In de vorige voorbeelden ziet u hoe de compiler de null-status voor lokale variabelen bepaalt wanneer deze wordt geïnitialiseerd, toegewezen of vergeleken met null.

De analyse van null-status traceert niet naar aangeroepen methoden. Als gevolg hiervan genereren velden die zijn geïnitialiseerd in een algemene helpermethode die door alle constructors wordt aangeroepen, een waarschuwing met de volgende sjabloon:

Niet-nullable eigenschap 'name' moet een niet-null-waarde bevatten bij het afsluiten van de constructor.

U kunt deze waarschuwingen op twee manieren aanpakken: constructorkoppeling of null-kenmerken in de helpermethode. In de volgende code ziet u een voorbeeld van elk. De Person klasse maakt gebruik van een algemene constructor die wordt aangeroepen door alle andere constructors. De Student klasse heeft een helpermethode die is voorzien van een aantekening met het System.Diagnostics.CodeAnalysis.MemberNotNullAttribute kenmerk:


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

Notitie

In C# 10 zijn een aantal verbeteringen toegevoegd aan de definitieve toewijzing en null-statusanalyse. Wanneer u een upgrade uitvoert naar C# 10, zijn er mogelijk minder null-waarschuwingen die fout-positieven zijn. Meer informatie over de verbeteringen in de functiesspecificatie voor definitieve toewijzingsverbeteringen.

Nullable state analysis and the warnings the compiler generates help you avoid program errors by dereferencing null. Het artikel over het oplossen van null-bare waarschuwingen biedt technieken voor het corrigeren van de waarschuwingen die waarschijnlijk in uw code worden weergegeven.

Kenmerken van API-handtekeningen

De analyse van null-status vereist hints van ontwikkelaars om inzicht te hebben in de semantiek van API's. Sommige API's bieden null-controles en moeten de null-status van een variabele wijzigen van misschien-null in not-null. Andere API's retourneren expressies die niet null of misschien null zijn, afhankelijk van de null-status van de invoerargumenten. Denk bijvoorbeeld aan de volgende code die een bericht in hoofdletters weergeeft:

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

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

Op basis van inspectie zou elke ontwikkelaar deze code veilig beschouwen en mag geen waarschuwingen genereren. De compiler weet echter niet dat IsNull er een null-controle wordt uitgevoerd en een waarschuwing voor de instructie wordt opgegeven, aangezien message deze message.ToUpper() een mogelijk null-variabele is. Gebruik het NotNullWhen kenmerk om deze waarschuwing op te lossen:

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

Met dit kenmerk wordt de compiler geïnformeerd dat de parameters, indien IsNull geretourneerdfalse, niet null is. De compiler wijzigt de null-status van message not-null in het if (!IsNull(message)) {...} blok. Er worden geen waarschuwingen gegeven.

Kenmerken bieden gedetailleerde informatie over de null-status van argumenten, retourwaarden en leden van het objectexemplaren die worden gebruikt om een lid aan te roepen. De details van elk kenmerk vindt u in het taalreferentieartikel over nullable reference attributes. Vanaf .NET 5 worden alle .NET Runtime-API's geannoteerd. U verbetert de statische analyse door aantekeningen te maken bij uw API's om semantische informatie te geven over de null-status van argumenten en retourwaarden.

Aantekeningen van null-variabelen

De analyse van null-status biedt een robuuste analyse voor lokale variabelen. De compiler heeft meer informatie van u nodig voor lidvariabelen. De compiler heeft meer informatie nodig om de null-status van alle velden in te stellen aan de vierkante haak openen van een lid. Een van de toegankelijke constructors kan worden gebruikt om het object te initialiseren. Als een lidveld ooit is ingesteld nullop, moet de compiler ervan uitgaan dat de null-status misschien null is aan het begin van elke methode.

U gebruikt aantekeningen die kunnen aangeven of een variabele een nullable verwijzingstype of een niet-nullable verwijzingstype is. Deze aantekeningen maken belangrijke instructies over de null-status voor variabelen:

  • Een verwijzing mag niet null zijn. De standaardstatus van een niet-null-referentievariabele is niet null. De compiler dwingt regels af die ervoor zorgen dat het veilig is om deze variabelen te deducteren zonder eerst te controleren of deze niet null is:
    • De variabele moet worden geïnitialiseerd naar een niet-null-waarde.
    • De variabele kan nooit de waarde nullworden toegewezen. De compiler geeft een waarschuwing wanneer code een misschien null-expressie toewijst aan een variabele die niet null mag zijn.
  • Een verwijzing kan null zijn. De standaardstatus van een variabele voor null-verwijzingen is misschien null. De compiler dwingt regels af om ervoor te zorgen dat u correct controleert op een null verwijzing:
    • De variabele kan alleen worden gededucteerd wanneer de compiler kan garanderen dat de waarde niet nullis.
    • Deze variabelen kunnen worden geïnitialiseerd met de standaardwaarde null en kunnen de waarde null in andere code worden toegewezen.
    • De compiler geeft geen waarschuwingen wanneer code een misschien-null-expressie toewijst aan een variabele die null kan zijn.

Elke niet-null-referentievariabele heeft een standaard null-status van not-null. Elke variabele voor null-verwijzingen heeft de initiële null-status van misschien-null.

Er wordt een null-verwijzingstype genoteerd met dezelfde syntaxis als null-waardetypen: een ? wordt toegevoegd aan het type variabele. De volgende variabeledeclaratie vertegenwoordigt bijvoorbeeld een variabele voor null-tekenreeksen: name

string? name;

Wanneer null-verwijzingstypen zijn ingeschakeld, is elke variabele waaraan de ? naam van het type niet is toegevoegd, een niet-null-verwijzingstype. Dit omvat alle referentietypevariabelen in bestaande code zodra u deze functie inschakelt. Impliciet getypte lokale variabelen (gedeclareerd met behulp van var) zijn echter null-referentietypen. Zoals in de voorgaande secties werd getoond, bepaalt statische analyse de null-status van lokale variabelen om te bepalen of ze misschien null zijn voordat deze worden uitgesteld.

Soms moet u een waarschuwing overschrijven wanneer u weet dat een variabele niet null is, maar de compiler bepaalt dat de null-status null is. U gebruikt de operator! null-forgiving na een variabelenaam om af te dwingen dat de null-status niet null is. Als u bijvoorbeeld weet dat de name variabele niet null is, maar de compiler een waarschuwing geeft, kunt u de volgende code schrijven om de analyse van de compiler te overschrijven:

name!.Length;

Null-referentietypen en null-waardetypen bieden een vergelijkbaar semantisch concept: een variabele kan een waarde of object vertegenwoordigen, of die variabele kan zijn null. Null-verwijzingstypen en null-waardetypen worden echter anders geïmplementeerd: null-waardetypen worden geïmplementeerd met behulp van System.Nullable<T>en null-verwijzingstypen worden geïmplementeerd door kenmerken die door de compiler worden gelezen. En beide worden bijvoorbeeld string?string vertegenwoordigd door hetzelfde type: System.String. int? En int worden echter vertegenwoordigd door System.Nullable<System.Int32> respectievelijkSystem.Int32.

Null-referentietypen zijn een functie voor het compileren van tijd. Dit betekent dat bellers waarschuwingen kunnen negeren, opzettelijk als argument worden gebruikt null voor een methode die een niet-null-bare verwijzing verwacht. Auteurs van bibliotheken moeten runtimecontroles opnemen op basis van null-argumentwaarden. De ArgumentNullException.ThrowIfNull optie is de voorkeursoptie voor het controleren van een parameter op null tijdens runtime.

Belangrijk

Het inschakelen van null-aantekeningen kan wijzigen hoe Entity Framework Core bepaalt of een gegevenslid vereist is. Meer informatie vindt u in het artikel over de basisprincipes van Entity Framework Core: Werken met Nullable Reference Types.

Generics

Voor generics zijn gedetailleerde regels vereist voor elke T? typeparameter T. De regels zijn noodzakelijkerwijs gedetailleerd vanwege de geschiedenis en de verschillende implementatie voor een type null-waarde en een null-referentietype. Null-waardetypen worden geïmplementeerd met behulp van de System.Nullable<T> struct. Null-referentietypen worden geïmplementeerd als typeaantekeningen die semantische regels aan de compiler bieden.

  • Als het typeargument T een verwijzingstype is, T? verwijst u naar het overeenkomstige null-verwijzingstype. Als T bijvoorbeeld een string, dan T? is het een string?.
  • Als het typeargument T voor een waardetype is, T? verwijst u naar hetzelfde waardetype, T. Als dit bijvoorbeeld T een intis, is het T? ook een int.
  • Als het typeargument T voor een null-verwijzingstype is, T? verwijst u naar hetzelfde null-verwijzingstype. Als dit bijvoorbeeld T een string?, dan is dat T? ook een string?.
  • Als het typeargument T voor een type null-waarde is, T? verwijst u naar hetzelfde type null-waarde. Als dit bijvoorbeeld T een int?, dan is dat T? ook een int?.

Voor retourwaarden is T? dit gelijk aan [MaybeNull]T; voor argumentwaarden is T? dit gelijk aan [AllowNull]T. Zie het artikel over kenmerken voor analyse van null-status in de taalverwijzing voor meer informatie.

U kunt verschillende gedragingen opgeven met behulp van beperkingen:

  • De class beperking betekent dat dit T een niet-null-verwijzingstype moet zijn (bijvoorbeeld string). De compiler produceert een waarschuwing als u een null-verwijzingstype gebruikt, zoals string? voor T.
  • De class? beperking betekent dat T dit een verwijzingstype moet zijn, niet-nullable (string) of een nullable verwijzingstype (bijvoorbeeld string?). Wanneer de typeparameter een nullable verwijzingstype is, zoals string?een expressie van T? verwijzingen die hetzelfde nullable verwijzingstype hebben, zoals string?.
  • De notnull beperking betekent dat dit T een niet-null-verwijzingstype of een niet-null-waardetype moet zijn. Als u een null-verwijzingstype of een null-waardetype voor de typeparameter gebruikt, genereert de compiler een waarschuwing. T Als het een waardetype is, is de retourwaarde bovendien dat waardetype, niet het overeenkomstige type null-waarde.

Deze beperkingen helpen de compiler meer informatie te geven over hoe T wordt gebruikt. Dit helpt wanneer ontwikkelaars het type kiezen T en betere null-statusanalyse bieden wanneer een exemplaar van het algemene type wordt gebruikt.

Null-contexten

Voor kleine projecten kunt u null-referentietypen inschakelen, waarschuwingen corrigeren en doorgaan. Voor grotere projecten en oplossingen voor meerdere projecten kan dit echter een groot aantal waarschuwingen genereren. U kunt pragma's gebruiken om bestand-per-bestand met null-verwijzingstypen in te schakelen wanneer u begint met het gebruik van null-referentietypen. De nieuwe functies die beschermen tegen het genereren van een System.NullReferenceException bestand, kunnen storend zijn wanneer ze zijn ingeschakeld in een bestaande codebasis:

  • Alle expliciet getypte referentievariabelen worden geïnterpreteerd als niet-nullable verwijzingstypen.
  • De betekenis van de class beperking in generieken is gewijzigd in een verwijzingstype dat niet null kan worden gebruikt.
  • Er worden nieuwe waarschuwingen gegenereerd vanwege deze nieuwe regels.

De context van de null-aantekening bepaalt het gedrag van de compiler. Er zijn vier waarden voor de context van de null-aantekening:

  • uitschakelen: de code is nullable-ob vergetelheid. Uitschakelen komt overeen met het gedrag voordat null-verwijzingstypen zijn ingeschakeld, behalve dat de nieuwe syntaxis waarschuwingen produceert in plaats van fouten.
    • Null-waarschuwingen zijn uitgeschakeld.
    • Alle referentietypevariabelen zijn null-referentietypen.
    • Het gebruik van het ? achtervoegsel om een nullable verwijzingstype te declareren, produceert een waarschuwing.
    • U kunt de operator null forgiving gebruiken, !maar dit heeft geen effect.
  • inschakelen: de compiler maakt alle null-referentieanalyses en alle taalfuncties mogelijk.
    • Alle nieuwe null-bare waarschuwingen zijn ingeschakeld.
    • U kunt het ? achtervoegsel gebruiken om een null-verwijzingstype te declareren.
    • Verwijzingstypevariabelen zonder achtervoegsel ? zijn niet-nullbare verwijzingstypen.
    • De operator null forgiving onderdrukt waarschuwingen voor een mogelijke toewijzing aan null.
  • waarschuwingen: de compiler voert alle null-analyses uit en verzendt waarschuwingen wanneer de code mogelijk deductie nulluitvoert.
    • Alle nieuwe null-bare waarschuwingen zijn ingeschakeld.
    • Het gebruik van het ? achtervoegsel om een nullable verwijzingstype te declareren, produceert een waarschuwing.
    • Alle referentietypevariabelen mogen null zijn. Leden hebben echter de null-statusnot-null bij de accolade openen van alle methoden, tenzij ze zijn gedeclareerd met het ? achtervoegsel.
    • U kunt de operator null forgiving gebruiken. !
  • aantekeningen: de compiler verzendt geen waarschuwingen wanneer code mogelijk deductie nullkan doen of wanneer u een mogelijk null-expressie toewijst aan een variabele die niet null kan zijn.
    • Alle nieuwe nullable-waarschuwingen zijn uitgeschakeld.
    • U kunt het ? achtervoegsel gebruiken om een null-verwijzingstype te declareren.
    • Verwijzingstypevariabelen zonder achtervoegsel ? zijn niet-nullbare verwijzingstypen.
    • U kunt de operator null forgiving gebruiken, !maar dit heeft geen effect.

De context van de null-aantekening en de context van null-waarschuwingen kunnen worden ingesteld voor een project met behulp van het <Nullable> element in uw .csproj-bestand . Dit element configureert hoe de compiler de null-waarde van typen interpreteert en welke waarschuwingen worden verzonden. In de volgende tabel worden de toegestane waarden weergegeven en worden de contexten samengevat die ze opgeven.

Context Waarschuwingen voor de deductie Toewijzingswaarschuwingen Verwijzingstypen ? Achtervoegsel ! Operator
disable Disabled Disabled Alle zijn nullable Hiermee wordt een waarschuwing gegenereerd Heeft geen effect
enable Ingeschakeld Ingeschakeld Niet-nullable tenzij gedeclareerd met ? Declareert nullable type Onderdrukt waarschuwingen voor mogelijke null toewijzingen
warnings Ingeschakeld Niet van toepassing Alle zijn null-baar, maar leden worden beschouwd als niet-null bij het openen van accolades van methoden Hiermee wordt een waarschuwing gegenereerd Onderdrukt waarschuwingen voor mogelijke null toewijzingen
annotations Disabled Disabled Niet-nullable tenzij gedeclareerd met ? Declareert nullable type Heeft geen effect

Variabelen voor verwijzingstypen in code die zijn gecompileerd in een uitgeschakelde context, zijn null-vergetelbaar. U kunt een null letterlijke waarde of een misschien null-variabele toewijzen aan een variabele die null-vergetelbaar is. De standaardstatus van een variabele met null-vergetelheid is echter niet null.

U kunt kiezen welke instelling het beste is voor uw project:

  • Kies uitschakelen voor verouderde projecten die u niet wilt bijwerken op basis van diagnostische gegevens of nieuwe functies.
  • Kies waarschuwingen om te bepalen waar uw code kan worden gegooid System.NullReferenceException. U kunt deze waarschuwingen aanpakken voordat u code wijzigt om niet-nullable verwijzingstypen in te schakelen.
  • Kies aantekeningen om uw ontwerpintentie uit te drukken voordat u waarschuwingen inschakelt.
  • Kies Inschakelen voor nieuwe projecten en actieve projecten waarvoor u wilt beveiligen tegen null-referentie-uitzonderingen.

Voorbeeld:

<Nullable>enable</Nullable>

U kunt ook instructies gebruiken om overal in uw broncode dezelfde contexten in te stellen. Deze instructies zijn het handigst wanneer u een grote codebasis migreert.

  • #nullable enable: Hiermee stelt u de context van de null-aantekening en de context van null-waarschuwingen in om deze in te schakelen.
  • #nullable disable: Hiermee stelt u de context van de null-aantekening en de null-waarschuwingscontext in om uit te schakelen.
  • #nullable restore: hiermee herstelt u de context van de null-aantekening en de context van null-waarschuwingen naar de projectinstellingen.
  • #nullable disable warnings: Stel de context van de null-waarschuwing in om uit te schakelen.
  • #nullable enable warnings: Stel de context voor null-waarschuwingen in om deze in te schakelen.
  • #nullable restore warnings: hiermee herstelt u de context van de waarschuwing die null kan worden gebruikt voor de projectinstellingen.
  • #nullable disable annotations: Stel de context voor null-aantekening in om uit te schakelen.
  • #nullable enable annotations: Stel de context voor null-aantekening in om deze in te schakelen.
  • #nullable restore annotations: Hiermee herstelt u de waarschuwingscontext voor aantekeningen naar de projectinstellingen.

Voor elke regel code kunt u een van de volgende combinaties instellen:

Waarschuwingscontext Aantekeningscontext Gebruik
standaardproject standaardproject Standaardinstelling
inschakelen uitschakelen Analysewaarschuwingen herstellen
inschakelen standaardproject Analysewaarschuwingen herstellen
standaardproject inschakelen Typeaantekeningen toevoegen
inschakelen inschakelen Code is al gemigreerd
uitschakelen inschakelen Aantekeningen toevoegen aan code voordat waarschuwingen worden opgelost
uitschakelen uitschakelen Verouderde code toevoegen aan gemigreerd project
standaardproject uitschakelen Zelden
uitschakelen standaardproject Zelden

Deze negen combinaties bieden u nauwkeurige controle over de diagnostische gegevens die de compiler verzendt voor uw code. U kunt meer functies inschakelen in elk gebied dat u bijwerkt, zonder dat u meer waarschuwingen ziet die u nog niet kunt adresseren.

Belangrijk

De globale null-context is niet van toepassing op gegenereerde codebestanden. Onder een van beide strategieën wordt de null-context uitgeschakeld voor elk bronbestand dat is gemarkeerd als gegenereerd. Dit betekent dat api's in gegenereerde bestanden niet worden geannoteerd. Er zijn vier manieren waarop een bestand wordt gemarkeerd als gegenereerd:

  1. Geef generated_code = true in de .editorconfig een sectie op die van toepassing is op dat bestand.
  2. Plaats <auto-generated> of <auto-generated/> in een opmerking boven aan het bestand. Het kan op elke regel in die opmerking staan, maar het opmerkingenblok moet het eerste element in het bestand zijn.
  3. Start de bestandsnaam met TemporaryGeneratedFile_
  4. Beëindig de bestandsnaam met .designer.cs, .generated.cs, .g.cs of .g.i.cs.

Generatoren kunnen zich aanmelden met behulp van de #nullable preprocessorrichtlijn.

Standaard worden aantekenings- en waarschuwingscontexten uitgeschakeld. Dit betekent dat uw bestaande code wordt gecompileerd zonder wijzigingen en zonder nieuwe waarschuwingen te genereren. Vanaf .NET 6 bevatten nieuwe projecten het <Nullable>enable</Nullable> element in alle projectsjablonen.

Deze opties bieden twee verschillende strategieën voor het bijwerken van een bestaande codebasis voor het gebruik van null-referentietypen.

Bekende valkuilen

Matrices en structs die verwijzingstypen bevatten, zijn bekende valkuilen in null-verwijzingen en de statische analyse die null-veiligheid bepaalt. In beide situaties kan een niet-null-bare verwijzing worden geïnitialiseerd, nullzonder waarschuwingen te genereren.

Structs

Met een struct die niet-nullbare verwijzingstypen bevat, kan deze zonder waarschuwingen worden toegewezen default . Kijk een naar het volgende voorbeeld:

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

In het voorgaande voorbeeld wordt er geen waarschuwing weergegeven PrintStudent(default) , terwijl de niet-nullbare verwijzingstypen FirstName null zijn en LastName null zijn.

Een andere veelvoorkomende zaak is wanneer u met algemene structs te maken krijgt. Kijk een naar het volgende voorbeeld:

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

In het voorgaande voorbeeld is null de eigenschap Prop in runtime. Deze wordt zonder waarschuwingen toegewezen aan niet-nullable tekenreeksen.

Matrices

Matrices zijn ook een bekende valkuil in null-referentietypen. Bekijk het volgende voorbeeld dat geen waarschuwingen produceert:

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

In het voorgaande voorbeeld toont de declaratie van de matrix dat deze niet-nullable tekenreeksen bevat, terwijl de elementen allemaal zijn geïnitialiseerd tot null. Vervolgens wordt aan de variabele s een null waarde toegewezen (het eerste element van de matrix). Ten slotte wordt de variabele s deductie veroorzaakt door een runtime-uitzondering.

Zie ook