Как Decimal.Round() выкидывать OverflowException

Я использую

Decimal.Round(decimal d)

MSDN говорит, что он может бросить OverflowException https://msdn.microsoft.com/en-us/library/k4e2bye2(v=vs.110).aspx

Я не уверен, как это может произойти. Я попытался просмотреть реализацию с помощью ilSpy И получил до внешней реализации:

// decimal
[SecurityCritical]
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern void FCallRound(ref decimal d, int decimals);

Кто-нибудь понял, какой ввод может вызвать это исключение?

Ответ 1

Когда мы идем дальше от того, что вы уже обнаружили, мы закончили реализацию функции VarDecRound. Эта функция имеет ровно одну ветвь, где он возвращает код ошибки, а именно, когда его второй аргумент cDecimals меньше нуля. Этот аргумент указывает число десятичных цифр для округления до:

if (cDecimals < 0) 
    return E_INVALIDARG; 

(это утверждение является эквивалентом того, что ArgumentException будет в .NET)

Как отметил Джеймс Торп в комментарии к OP, аналогичное утверждение выполняется дальше по цепочке звонков, здесь:

if (decimals < 0 || decimals > 28) 
    FCThrowArgumentOutOfRangeVoid(...)

Вывод:
Выполнение не может достигнуть точки, что приведет к тому, что OverflowException будет занесено в документ:

  • OverflowException, по-видимому, используется внутренне как механизм catch-all, очень похожий на OutOfMemoryException в GDI +
  • Документация не соответствует фактической реализации
  • OverflowException даже не имеет смысла концептуально. Округление значения вверх или вниз в одном и том же типе данных не может превышать интегральный минимальный или максимальный диапазон, поскольку значение кандидата должно быть в пределах диапазона (используется метод округления)