Эй, я использую 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;
}
На основе этой декомпиляции я ожидал бы, что это или переполнится или не в зависимости от контекста кода вызова. Почему это переполняется, и как я могу заставить это останавливаться?
Код действительно выполняется в блоке с проверкой 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
. Нет способа заставить этот конкретный метод не вызывать переполнение. Лучшие варианты:
long
проверено
применяется только к выражениям в текущем блоке, а не к любому (уже скомпилированному) вызываемому методу. Чтобы использовать непроверенные математические операции, вам необходимо реализовать свою собственную версию Sum
внутри unchecked
блока