Null-verwijzingstypen
Null-verwijzingstypen zijn een groep functies die de kans minimaliseren dat uw code ervoor zorgt dat de runtime System.NullReferenceExceptiongenereert. Drie functies waarmee u deze uitzonderingen kunt voorkomen, waaronder de mogelijkheid om expliciet een verwijzingstype te markeren als nullable:
- 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 volgende twee waarden:
-
not-null: de expressie is bekend dat deze niet
null
is. -
misschien-null: de expressie kan zijn
null
.
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.
In de rest van dit artikel wordt beschreven hoe deze drie functionaliteiten werken om waarschuwingen te genereren wanneer uw code mogelijk dereferentieert een null
waarde. 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.
Op dezelfde manier kunnen waarschuwingen worden gegenereerd wanneer []
notatie wordt gebruikt voor toegang tot een lid van een object wanneer het object:null
using System;
public class Collection<T>
{
private T[] array = new T[100];
public T this[int index]
{
get => array[index];
set => array[index] = value;
}
}
public static void Main()
{
Collection<int> c = default;
c[10] = 1; // CS8602: Possible derefence of null
}
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, parameters en retourwaarden om de standaard null-status in te stellen.
- 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. - De Nullbare context helpt u bij het migreren van grote projecten. U kunt waarschuwingen en aantekeningen inschakelen in de null-context in delen van uw app terwijl u migreert. Nadat u meer waarschuwingen hebt adresseert, kunt u beide instellingen 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
Null-toestandanalyse houdt de null-toestand van verwijzingen bij. Een expressie is niet null of misschien null. De compiler bepaalt dat een variabele niet null is op twee manieren:
- Aan de variabele is een waarde toegewezen die bekend staat als niet-nul.
- De variabele werd vergeleken met
null
en is sindsdien niet toegewezen.
Elke variabele die de compiler niet kan bepalen als niet-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-nullis, kan die variabele veilig worden gedereferentieerd.
- 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 kunnen velden die zijn geïnitialiseerd in een algemene helpermethode die door alle constructors wordt aangeroepen, een waarschuwing genereren met het volgende bericht:
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";
}
}
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. De diagnostische gegevens die worden geproduceerd uit null-statusanalyse, zijn alleen waarschuwingen.
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.ToUpper()
deze message
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 parameterIsNull
, indien false
geretourneerds
, 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 null
op, 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
null
worden 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 gedereferentieerd wanneer de compiler kan garanderen dat de waarde niet is
null
. - Deze variabelen kunnen worden geïnitialiseerd met de standaardwaarde
null
en kunnen worden toegewezen aan de waardenull
in andere code. - De compiler geeft geen waarschuwingen wanneer code een misschien-null-expressie toewijst aan een variabele die null kan zijn.
- De variabele kan alleen worden gedereferentieerd wanneer de compiler kan garanderen dat de waarde niet is
Elke niet-nulleerbare verwijzingsvariabele heeft de initiële null-status van niet-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 !
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. Bovendien is het runtimegedrag van een programma dat gebruikmaakt van null-aantekeningen hetzelfde als alle null-aantekeningen (?
en !
), worden verwijderd. Hun enige doel is het uitdrukken van ontwerpintentie en het verstrekken van informatie voor null-statusanalyse.
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. AlsT
bijvoorbeeld eenstring
, danT?
is het eenstring?
. - Als het typeargument
T
voor een waardetype is,T?
verwijst u naar hetzelfde waardetype,T
. Als dit bijvoorbeeldT
eenint
is, is hetT?
ook eenint
. - Als het typeargument
T
voor een null-verwijzingstype is,T?
verwijst u naar hetzelfde null-verwijzingstype. Als dit bijvoorbeeldT
eenstring?
, dan is datT?
ook eenstring?
. - Als het typeargument
T
voor een type null-waarde is,T?
verwijst u naar hetzelfde type null-waarde. Als dit bijvoorbeeldT
eenint?
, dan is datT?
ook eenint?
.
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 ditT
een niet-null-verwijzingstype moet zijn (bijvoorbeeldstring
). De compiler produceert een waarschuwing als u een null-verwijzingstype gebruikt, zoalsstring?
voorT
. - De
class?
beperking betekent datT
dit een verwijzingstype moet zijn, niet-nullable (string
) of een nullable verwijzingstype (bijvoorbeeldstring?
). Wanneer de typeparameter een nullable verwijzingstype is, zoalsstring?
een expressie vanT?
verwijzingen die hetzelfde nullable verwijzingstype hebben, zoalsstring?
. - De
notnull
beperking betekent dat ditT
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-context
De nullable context bepaalt hoe nullable referentietype-annotaties worden verwerkt en welke waarschuwingen worden gegenereerd door statische nulstatusanalyse. De null-context bevat twee vlaggen: de aantekeningsinstelling en de waarschuwingsinstelling.
Zowel de aantekening als waarschuwing instellingen zijn standaard uitgeschakeld voor bestaande projecten. Vanaf .NET 6 (C# 10) zijn beide vlaggen standaard ingeschakeld voor nieuwe projecten. De reden voor twee afzonderlijke vlaggen voor de nulbare context is om het eenvoudiger te maken om grote projecten te migreren die dateren van vóór de introductie van nulbare referentietypen.
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 combinaties voor de nullable-context-instellingen:
-
beide uitgeschakeld: de code is null-vergetend.
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.
-
beide ingeschakeld: de compiler schakelt alle null-referentieanalyse en alle taalfuncties in.
- 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 deductie van
null
.
- De waarschuwing ingeschakeld: de compiler voert alle null-analyses uit en geeft waarschuwingen wanneer code mogelijk dereferentie
null
.- 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 ingeschakeld: de compiler geeft geen waarschuwingen af wanneer code mogelijk dereferentiert
null
, of wanneer u een mogelijk-null-expressie toewijst aan een niet-null-variabele.- 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 |
! bediener |
---|---|---|---|---|---|
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 dezelfde vlaggen overal in uw broncode in te stellen. Deze instructies zijn het handigst wanneer u een grote codebasis migreert.
-
#nullable enable
: hiermee stelt u de aantekening en waarschuwingsvlagmen in om in te schakelen. -
#nullable disable
: Hiermee stelt u de annotatie- en waarschuwingsvlaggen in om uit te schakelen. -
#nullable restore
: hiermee herstelt u de aantekeningsvlag en waarschuwingsvlag naar de projectinstellingen. -
#nullable disable warnings
: stel de waarschuwingsvlag in op uitschakelen. -
#nullable enable warnings
: stel de waarschuwingsvlag in op inschakelen. -
#nullable restore warnings
: hiermee herstelt u de waarschuwingsvlag in de projectinstellingen. -
#nullable disable annotations
: stel de annotatievlag in op om uit te schakelen. -
#nullable enable annotations
: stel de aantekeningsvlag in op omin te schakelen. -
#nullable restore annotations
: hiermee herstelt u de aantekeningsvlag naar de projectinstellingen.
Voor elke regel code kunt u een van de volgende combinaties instellen:
Waarschuwingsvlag | Aantekeningsvlag | 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 worden geen nulbare waarschuwingen gegenereerd voor gegenereerde bestanden. Er zijn vier manieren waarop een bestand wordt gemarkeerd als gegenereerd:
- Geef
generated_code = true
in de .editorconfig een sectie op die van toepassing is op dat bestand. - 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. - Start de bestandsnaam met TemporaryGeneratedFile_
- 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 null-aantekenings- en waarschuwingsvlagmen uitgeschakeld. Dit betekent dat uw bestaande code wordt gecompileerd zonder wijzigingen en zonder nieuwe waarschuwingen te genereren. Vanaf .NET 6 bevatten nieuwe projecten het element <Nullable>enable</Nullable>
in alle projectsjablonen, waarbij u deze vlaggen instelt op ingeschakelde.
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, null
zonder 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 Prop
de eigenschap null
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.