Skip to content
Code quality Reviewed 2026-09-13

Right Shift Not Number

What does this mean ?

For the built-in C# shift operators on integral values, the shift count is an integer with defined masking semantics. Using dynamic defers binding checks until runtime, so an incompatible operand can compile but fail when executed. User-defined operators may have their own signatures and behavior.

What can happen ?

A bad dynamic operand can raise a runtime binding error. Even a valid integer count can produce an unexpected result: for a 32-bit operand, the built-in operator uses the low five bits of the count. A count of 32 therefore does not mean “shift all bits away.”

Recommendation

Prefer statically typed operands. Validate the count against the application's intended range rather than relying on implicit masking. Choose signed or unsigned values deliberately; signed right shift propagates the sign bit, while unsigned right shift fills with zeros.

Sample Code

// Incorrect for the built-in integer operation; fails during dynamic binding.
dynamic value = 5;
var broken = value >> 5.4;
static uint ShiftRight(uint value, int count)
{
    if (count < 0 || count > 31)
        throw new ArgumentOutOfRangeException(nameof(count));
    return value >> count;
}

The corrected helper deliberately permits counts 0–31 and uses an unsigned 32-bit value. This is a reliability policy, not automatically a security control.

Regression checks

Check counts 0, 1 and 31, and reject negative values and 32. Verify the high-bit case with an unsigned value. Test parsing at the boundary where external text becomes an integer.

References