markerade och avmarkerade instruktioner (C#-referens)
Instruktionen checked
och unchecked
anger överflödeskontrollkontexten för aritmetiska åtgärder av typen integraltyp och konverteringar. När heltalsaritmiskt spill inträffar definierar överflödeskontrollkontexten vad som händer. I en markerad kontext utlöses en System.OverflowException . Om spill inträffar i ett konstant uttryck uppstår ett kompileringsfel. I en omarkerad kontext trunkeras åtgärdsresultatet genom att alla bitar i hög ordning som inte får plats i måltypen ignoreras. Om du till exempel lägger till det omsluts det från det maximala värdet till det minsta värdet. I följande exempel visas samma åtgärd i både en markerad och omarkerad kontext:
uint a = uint.MaxValue;
unchecked
{
Console.WriteLine(a + 3); // output: 2
}
try
{
checked
{
Console.WriteLine(a + 3);
}
}
catch (OverflowException e)
{
Console.WriteLine(e.Message); // output: Arithmetic operation resulted in an overflow.
}
Kommentar
Beteendet för användardefinierade operatorer och konverteringar vid spill kan skilja sig från det som beskrivs i föregående stycke. I synnerhet kanske användardefinierade kontrollerade operatorer inte utlöser ett undantag i en kontrollerad kontext.
Mer information finns i avsnittet Aritmetiska spill och division med noll och användardefinierade kontrollerade operatorer i artikeln Aritmetiska operatorer .
Om du vill ange kontexten för spillkontroll för ett uttryck kan du också använda operatorerna checked
och unchecked
, som följande exempel visar:
double a = double.MaxValue;
int b = unchecked((int)a);
Console.WriteLine(b); // output: -2147483648
try
{
b = checked((int)a);
}
catch (OverflowException e)
{
Console.WriteLine(e.Message); // output: Arithmetic operation resulted in an overflow.
}
Operatorerna checked
och unchecked
och påverkar bara överflödeskontrollkontexten för de åtgärder som är textuellt inuti instruktionsblocket eller operatorns parenteser, som följande exempel visar:
int Multiply(int a, int b) => a * b;
int factor = 2;
try
{
checked
{
Console.WriteLine(Multiply(factor, int.MaxValue)); // output: -2
}
}
catch (OverflowException e)
{
Console.WriteLine(e.Message);
}
try
{
checked
{
Console.WriteLine(Multiply(factor, factor * int.MaxValue));
}
}
catch (OverflowException e)
{
Console.WriteLine(e.Message); // output: Arithmetic operation resulted in an overflow.
}
I föregående exempel visar den första anropet av den Multiply
lokala funktionen att instruktionen checked
inte påverkar överflödeskontrollkontexten Multiply
i funktionen eftersom inget undantag utlöses. Vid funktionens andra anrop Multiply
utvärderas uttrycket som beräknar funktionens andra argument i en kontrollerad kontext och resulterar i ett undantag eftersom det är textmässigt inuti -blocket i -instruktionen checked
.
Åtgärder som påverkas av överflödeskontrollkontexten
Kontexten för spillkontroll påverkar följande åtgärder:
Följande inbyggda aritmetiska operatorer: unary
++
,--
,-
och binary+
,-
,*
och/
operatorer, när deras operander är av en integrerad typ (dvs. antingen integral numerisk eller teckentyp ) eller en uppräkningstyp .Explicita numeriska konverteringar mellan integraltyper eller från
float
ellerdouble
till en integrerad typ.Kommentar
När du konverterar ett
decimal
värde till en integrerad typ och resultatet ligger utanför måltypens intervall genereras alltid ett OverflowException värde, oavsett kontexten för spillkontroll.Från och med C# 11, användardefinierade kontrollerade operatorer och konverteringar. Mer information finns i avsnittet Användardefinierade kontrollerade operatorer i artikeln Aritmetiska operatorer .
Standardkontext för spillkontroll
Om du inte anger kontexten för spillkontroll definierar värdet för kompileringsalternativet CheckForOverflowUnderflow standardkontexten för icke-konstanta uttryck. Som standard är värdet för det alternativet oetat och aritmetiska åtgärder av typen integraltyp och konverteringar körs i en omarkerad kontext.
Konstanta uttryck utvärderas som standard i en kontrollerad kontext och ett kompileringsfel uppstår vid spill. Du kan uttryckligen ange en omarkerad kontext för ett konstant uttryck med instruktionen unchecked
eller operatorn.
Språkspecifikation för C#
Mer information finns i följande avsnitt i C#-språkspecifikationen:
- De markerade och omarkerade uttrycken
- De markerade och avmarkerade operatorerna
- Användardefinierade markerade och avmarkerade operatorer – C# 11