Zaškrtnuté a nezaškrtnuté příkazy (referenční dokumentace jazyka C#)
unchecked
Příkazy checked
určují kontext kontroly přetečení pro aritmetické operace a převody celočíselného typu. Když dojde k aritmetickému přetečení celého čísla, kontext kontroly přetečení definuje, co se stane. V kontrolovaném kontextu System.OverflowException je vyvolán. Pokud dojde k přetečení v konstantním výrazu, dojde k chybě v době kompilace. V nezaškrtnutém kontextu se výsledek operace zkrátí tak, že zahodí všechny bity s vysokým pořadím, které se nevejdou do cílového typu. Například přidání se zabalí z maximální hodnoty na minimální hodnotu. Následující příklad ukazuje stejnou operaci v zaškrtnutém i nezaškrtnutém kontextu:
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.
}
Poznámka:
Chování přetečení uživatelem definovaných operátorů a převodů se může lišit od chování popsaného v předchozím odstavci. Konkrétně uživatelem definované kontrolované operátory nemusí vyvolat výjimku v kontrolovaném kontextu.
Další informace najdete v oddílech Aritmetických přetečení a dělení nulou a uživatelem definovanými operátory v článku Aritmetické operátory.
Pokud chcete zadat kontext kontroly přetečení výrazu, můžete také použít operátory checked
a unchecked
operátory, jak ukazuje následující příklad:
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.
}
Příkazy checked
a unchecked
operátory mají vliv pouze na kontext kontroly přetečení pro operace, které jsou textově uvnitř bloku příkazu nebo závorek operátoru, jak ukazuje následující příklad:
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.
}
V předchozím příkladu první vyvolání Multiply
místní funkce ukazuje, že checked
příkaz nemá vliv na kontext kontroly přetečení v rámci Multiply
funkce, protože není vyvolán žádná výjimka. Při druhém vyvolání Multiply
funkce se výraz, který vypočítá druhý argument funkce, vyhodnotí v kontrolovaném kontextu a výsledkem je výjimka, protože je textově uvnitř bloku checked
příkazu.
Chování checked
a unchecked
závisí na typu a operaci. Dokonce i pro celá čísla, operace unchecked(x / 0)
jako vždy házet, protože neexistuje rozumné chování. Zkontrolujte chování typu a operace, abyste pochopili, jak ovlivňují checked
kód a unchecked
klíčová slova.
Číselné typy a kontext kontroly přetečení
Klíčová checked
slova se unchecked
primárně vztahují na integrální typy, kde je rozumné chování přetečení. Zalomení chování, kde T.MaxValue + 1
se stává T.MinValue
rozumné ve dvou doplňovací hodnotě. Reprezentovaná hodnota není správná , protože se nedá vejít do úložiště pro daný typ. Bity proto představují nižší počet bitů celého výsledku.
U typů, jako decimal
je , float
, double
a Half
které představují složitější hodnotu nebo hodnotu doplňku, není zalomení rozumné. Nedá se použít k výpočtu větších nebo přesnějších výsledků, takže unchecked
to není výhodné.
float
, double
a Half
mít rozumné nasycení hodnot pro PositiveInfinity
a NegativeInfinity
, takže můžete detekovat přetečení v unchecked
kontextu. Neexistují decimal
žádná taková omezení a nasycení MaxValue
může vést k chybám nebo nejasnostem. Operace, které používají decimal
vyvolání v kontextu i unchecked
v checked
kontextu.
Operace ovlivněné kontextem kontroly přetečení
Kontext kontroly přetečení má vliv na následující operace:
Následující předdefinované aritmetické operátory: unární
++
,--
-
a binární+
,-
,*
a/
operátory, pokud jsou jejich operandy celočíselného typu (tj. celočíselný číselný nebo znakový typ) nebo výčtový typ.Explicitní číselné převody mezi integrálními typy nebo z
float
nebodouble
celočíselným typem.Poznámka:
Při převodu
decimal
hodnoty na celočíselný typ a výsledek je mimo rozsah cílového typu, je vždy vyvolán bez OverflowException ohledu na kontext kontroly přetečení.Počínaje jazykem C# 11, uživatelem definovanými operátory a převody. Další informace naleznete v části Uživatelem definované kontrolované operátory článku Aritmetické operátory.
Výchozí kontext kontroly přetečení
Pokud nezadáte kontext kontroly přetečení, definuje hodnota možnosti kompilátoru CheckForOverflowUnderflow výchozí kontext pro nekonstantní výrazy. Ve výchozím nastavení se hodnota této možnosti nespustí a aritmetické operace a převody celočíselného typu v nezaškrtnutém kontextu.
Konstantní výrazy se ve výchozím nastavení vyhodnocují v kontrolovaném kontextu a přetečení způsobí chybu v době kompilace. Pomocí příkazu nebo operátoru můžete explicitně zadat nezaškrtnutý kontext pro konstantní výraz unchecked
.
specifikace jazyka C#
Další informace najdete v následujících částech specifikace jazyka C#:
- Zaškrtnuté a nezaškrtnuté příkazy
- Zaškrtnuté a nezaškrtnuté operátory
- Uživatelem definované zaškrtnuté a nezaškrtnuté operátory – C# 11