Dela via


Typer av null-värden (C#-referens)

En nullbar värdetypT? representerar alla värden av dess underliggande värdetypT och ytterligare ett null-värde . Du kan till exempel tilldela något av följande tre värden till en bool? variabel: true, falseeller null. En underliggande värdetyp T kan inte vara en nullbar värdetyp.

C#-språkreferensen dokumenterar den senaste versionen av C#-språket. Den innehåller även inledande dokumentation för funktioner i offentliga förhandsversioner för den kommande språkversionen.

Dokumentationen identifierar alla funktioner som först introducerades i de tre senaste versionerna av språket eller i aktuella offentliga förhandsversioner.

Tips/Råd

Information om när en funktion först introducerades i C# finns i artikeln om språkversionshistoriken för C#.

Alla null-värdetyper är en instans av den allmänna System.Nullable<T> strukturen. Du kan referera till en nullbar värdetyp med en underliggande typ T i något av följande utbytbara formulär: Nullable<T> eller T?.

Använd vanligtvis en nullbar värdetyp när du behöver representera det odefinierade värdet för en underliggande värdetyp. En boolesk variabel boolkan till exempel bara vara antingen true eller false. I vissa program kan dock ett variabelvärde vara odefinierat eller saknas. Ett databasfält kan till exempel innehålla true eller false, eller så kanske det inte innehåller något värde alls, det vill säga NULL. Du kan använda typen bool? i det scenariot.

Deklaration och tilldelning

Eftersom en värdetyp implicit kan konverteras till motsvarande null-värdetyp kan du tilldela ett värde till en variabel av en nullbar värdetyp som du gör för dess underliggande värdetyp. Du kan också tilldela värdet null . Till exempel:

double? pi = 3.14;
char? letter = 'a';

int m2 = 10;
int? m = m2;

bool? flag = null;

// An array of a nullable value type:
int?[] arr = new int?[10];

Standardvärdet för en nullbar värdetyp representerar null. Det är en instans vars Nullable<T>.HasValue egenskap returnerar false.

Undersökning av en instans av en nullbar värdetyp

Om du vill kontrollera en instans av en nullbar värdetyp för null och hämta ett värde av en underliggande typ använder du operatornis med ett typmönster:

int? a = 42;
if (a is int valueOfA)
{
    Console.WriteLine($"a is {valueOfA}");
}
else
{
    Console.WriteLine("a does not have a value");
}
// Output:
// a is 42

Du kan alltid använda följande skrivskyddade egenskaper för att kontrollera och hämta ett värde för en nullbar värdetypsvariabel:

I följande exempel används HasValue egenskapen för att kontrollera om variabeln innehåller ett värde innan den visas:

int? b = 10;
if (b.HasValue)
{
    Console.WriteLine($"b is {b.Value}");
}
else
{
    Console.WriteLine("b does not have a value");
}
// Output:
// b is 10

Du kan också jämföra en variabel av en nullbar värdetyp med null i stället för att HasValue använda egenskapen, som följande exempel visar:

int? c = 7;
if (c != null)
{
    Console.WriteLine($"c is {c.Value}");
}
else
{
    Console.WriteLine("c does not have a value");
}
// Output:
// c is 7

Konvertering från en nullbar värdetyp till en underliggande typ

Om du vill tilldela ett värde av en nullbar värdetyp till en variabel av typen icke-nullbar värdetyp kan du behöva ange det värde som ska tilldelas i stället för null. Använd operatorn ??null-coalescing för att göra det. Du kan också använda Nullable<T>.GetValueOrDefault(T) metoden för samma ändamål:

int? a = 28;
int b = a ?? -1;
Console.WriteLine($"b is {b}");  // output: b is 28

int? c = null;
int d = c ?? -1;
Console.WriteLine($"d is {d}");  // output: d is -1

Om du vill använda standardvärdet för den underliggande värdetypen i stället för nullanvänder du Nullable<T>.GetValueOrDefault() metoden .

Du kan också uttryckligen omvandla en nullbar värdetyp till en icke-nullbar typ, vilket visas i följande exempel:

int? n = null;

//int m1 = n;    // Doesn't compile
int n2 = (int)n; // Compiles, but throws an exception if n is null

Vid körningen, om värdet för en nullbar värdetyp är null, genererar den explicita casten en InvalidOperationException.

En värdetyp som T inte kan nollföras kan implicit konverteras till motsvarande nullbara värdetyp T?.

Upplyfta operatorer

En nullbar värdetyp T? stöder fördefinierade odefinierade och binära operatorer eller överlagrade operatorer som en värdetyp T stöder. Dessa operatorer, även kallade lyftoperatorer, returnerar null om en eller båda operanderna är null. Annars använder operatorn de inneslutna värdena för sina operander för att beräkna resultatet. Till exempel:

int? a = 10;
int? b = null;
int? c = 10;

a++;        // a is 11
a = a * c;  // a is 110
a = a + b;  // a is null

Kommentar

bool? För typen följer de fördefinierade & operatorerna | inte de regler som beskrivs i det här avsnittet: resultatet av en operatorutvärdering kan vara icke-null även om någon av operanderna är null. Mer information finns i avsnittet Booleska logiska operatorer som kan ogiltigförklaras i artikeln Booleska logiska operatorer .

För jämförelseoperatorerna< , <=>, och >=, om en eller båda operanderna är null, blir falseresultatet . I annat fall jämförs de inneslutna värdena för operander. Anta inte att eftersom en viss jämförelse (till exempel <=) returnerar returnerar falsetrueden motsatta jämförelsen (>). Följande exempel visar att 10 är

  • varken större än eller lika med null
  • eller mindre än null
int? a = 10;
Console.WriteLine($"{a} >= null is {a >= null}");
Console.WriteLine($"{a} < null is {a < null}");
Console.WriteLine($"{a} == null is {a == null}");
// Output:
// 10 >= null is False
// 10 < null is False
// 10 == null is False

int? b = null;
int? c = null;
Console.WriteLine($"null >= null is {b >= c}");
Console.WriteLine($"null == null is {b == c}");
// Output:
// null >= null is False
// null == null is True

För likhetsoperatorn== är resultatet om båda operanderna är nulltrue. Om bara en av operanderna är nullär falseresultatet . I annat fall jämförs de inneslutna värdena för operander.

För ojämlikhetsoperatorn!= är resultatet om båda operanderna är nullfalse. Om bara en av operanderna är nullär trueresultatet . I annat fall jämförs de inneslutna värdena för operander.

Om det finns en användardefinierad konvertering mellan två värdetyper kan samma konvertering också användas mellan motsvarande nullbara värdetyper.

Boxning och avboxning

Följande regler gäller när du boxar en instans av en nullbar värdetyp T?:

  • Om HasValue returnerar falsereturnerar boxningsåtgärden null-referensen.
  • Om HasValue returnerar truerutor boxningsåtgärden motsvarande värde för den underliggande värdetypen T, inte instansen av Nullable<T>.

Du kan ta bort ett rutat värde av en värdetyp T till motsvarande nullbar värdetyp T?, som följande exempel visar:

int a = 41;
object aBoxed = a;
int? aNullable = (int?)aBoxed;
Console.WriteLine($"Value of aNullable: {aNullable}");

object aNullableBoxed = aNullable;
if (aNullableBoxed is int valueOfA)
{
    Console.WriteLine($"aNullableBoxed is boxed int: {valueOfA}");
}
// Output:
// Value of aNullable: 41
// aNullableBoxed is boxed int: 41

Så här identifierar du en värdetyp som kan ogiltigförklaras

I följande exempel visas hur du avgör om en System.Type instans representerar en konstruerad nullbar värdetyp, System.Nullable<T> det vill säga typen med en angiven typparameter T:

Console.WriteLine($"int? is {(IsNullable(typeof(int?)) ? "nullable" : "non nullable")} value type");
Console.WriteLine($"int is {(IsNullable(typeof(int)) ? "nullable" : "non-nullable")} value type");

bool IsNullable(Type type) => Nullable.GetUnderlyingType(type) != null;

// Output:
// int? is nullable value type
// int is non-nullable value type

Som exemplet visar använder du typ av operator för att skapa en System.Type instans.

Om du vill ta reda på om en instans har en värdetyp som kan vara null ska du inte använda Object.GetType metoden för att hämta en Type instans att testa med hjälp av föregående kod. När du anropar Object.GetType metoden på en instans av en nullbar värdetyp, boxas instansen till Object. Eftersom boxning av en icke-null-instans av en nullbar värdetyp motsvarar boxning av ett värde av den underliggande typen, GetType returnerar en Type instans som representerar den underliggande typen av en nullbar värdetyp:

int? a = 17;
Type typeOfA = a.GetType();
Console.WriteLine(typeOfA.FullName);
// Output:
// System.Int32

Använd inte heller is-operatorn för att avgöra om en instans är av en nullbar värdetyp. Som i följande exempel visas kan du inte skilja mellan typer av en nullbar värdetypsinstans och dess underliggande typinstans med hjälp av operatorn is :

int? a = 14;
if (a is int)
{
    Console.WriteLine("int? instance is compatible with int");
}

int b = 17;
if (b is int?)
{
    Console.WriteLine("int instance is compatible with int?");
}
// Output:
// int? instance is compatible with int
// int instance is compatible with int?

Använd Nullable.GetUnderlyingType i stället metoden från det första exemplet och typ av operator för att kontrollera om en instans är av en nullbar värdetyp.

Kommentar

Metoderna som beskrivs i det här avsnittet gäller inte för null-referenstyper.

Språkspecifikation för C#

Mer information finns i följande avsnitt i C#-språkspecifikationen:

Se även