Skip to main content
The checked keyword in C# explicitly enables arithmetic overflow checking for integral-type operations, enum operations, explicit numeric conversions, and user-defined types implementing checked operators. When an operation inside a checked context produces a result that exceeds the maximum or minimum bounds of the destination data type, the Common Language Runtime (CLR) throws a System.OverflowException instead of silently wrapping or truncating the value. You can apply checked in two ways: as an operator for a single expression, or as a statement block for multiple expressions. Operator Syntax:
Statement Block Syntax:

Technical Mechanics

  • Affected Types: The checked context applies to integral types (sbyte, byte, short, ushort, int, uint, long, ulong, char, nint, and nuint), enum types (which are backed by integral types), and user-defined struct or class types that implement checked operator overloads.
  • User-Defined Checked Operators (C# 11+): Developers can define custom overflow behavior for user-defined types using the checked modifier on operator overloads. When an operation is invoked inside a checked context, the compiler resolves to the checked variant of the operator if it exists. Note that declaring a checked operator requires also declaring its matching non-checked version to avoid a compile-time error (CS9025).
  • Floating-Point and Decimal Types: Floating-point arithmetic operations (float, double) are unaffected by checked and resolve to Infinity on overflow. However, explicit casts from floating-point types to integral types are strictly evaluated for overflow within a checked context. The decimal type always throws an OverflowException on arithmetic overflow, regardless of the checking context.
  • Affected Operations: The context enforces bounds checking on the following operations:
    • Binary arithmetic operators: +, -, *
    • Unary operators: -, ++, --
    • Explicit numeric conversions (casts) between integral types or enums.
    • Explicit numeric conversions (casts) from floating-point types (float, double) to integral types.
    • User-defined operators explicitly marked with the checked modifier.
  • Compile-Time vs. Runtime: By default, C# evaluates non-constant integral expressions at runtime in an unchecked context (unless the /checked compiler flag is enabled). The checked keyword forces the compiler to emit overflow-aware IL (Intermediate Language) instructions. For arithmetic, it emits add.ovf, sub.ovf, or mul.ovf instead of the standard add, sub, or mul instructions. For explicit conversions, it emits conv.ovf.* instructions (e.g., conv.ovf.i4) instead of standard conversion instructions (e.g., conv.i4). Constant expressions are always checked at compile-time, regardless of the presence of the checked keyword, unless explicitly wrapped in an unchecked block.

Lexical Scoping Limitation

The checked environment is strictly lexically scoped. It only applies to the operations textually written within the parentheses or braces. It does not propagate down the call stack to methods invoked within the block.
Tired of Poor C# Skills? Fix That With Deep Grasping!Learn More