Счетный. Сумма () переполнение

Эй, я использую Enumerable.Sum() дополнительный метод от LINQ для вычислений хэш-кодов, и имеет проблему с OverflowExceptions когда код становится большим. Я пытался вставить вызов unchecked блок, но это, казалось, не помогло.

В документации MSDN для метода говорится, что это бросит, если значение станет слишком большим, но я зарегистрировался в отражателе, и это - все, которое существует:

public static int Sum(this IEnumerable<int> source) {
    if (source == null) {
        throw Error.ArgumentNull("source");
    }
    int num = 0;
    foreach (int num2 in source) {
        num += num2;
    }
    return num;
}

На основе этой декомпиляции я ожидал бы, что это или переполнится или не в зависимости от контекста кода вызова. Почему это переполняется, и как я могу заставить это останавливаться?

12
задан JaredPar 5 February 2010 в 17:04
поделиться

2 ответа

Код действительно выполняется в блоке с проверкой C # . Проблема в том, что рефлектор неправильно декомпилирует проверенные блоки и вместо этого отображает их как обычные математические операции. Вы можете убедиться в этом сами, создав отмеченный блок, скомпилировав код и затем декомпилировав его в отражателе.

Вы также можете проверить это, посмотрев на IL вместо декомпилированного кода C #. Вместо кода операции добавления IL вы увидите, что добавление происходит с помощью add.ovf. Это версия add, которая вызывает переполнение

L_001a: callvirt instance !0 [mscorlib]System.Collections.Generic.IEnumerator`1<int32>::get_Current()
L_001f: stloc.1 
L_0020: ldloc.0 
L_0021: ldloc.1 
L_0022: add.ovf <-- This is an overflow aware addition
L_0023: stloc.0 
L_0024: ldloc.2 

. Нет способа заставить этот конкретный метод не вызывать переполнение. Лучшие варианты:

  1. Переключитесь на более крупный тип, например long
  2. Напишите свою собственную версию Sum, которая не использует проверяемое сложение
9
ответ дан 2 December 2019 в 19:54
поделиться

проверено применяется только к выражениям в текущем блоке, а не к любому (уже скомпилированному) вызываемому методу. Чтобы использовать непроверенные математические операции, вам необходимо реализовать свою собственную версию Sum внутри unchecked блока

1
ответ дан 2 December 2019 в 19:54
поделиться
Другие вопросы по тегам:

Похожие вопросы: