LINQ Странное исполнение - непоследовательно? - PullRequest
1 голос
/ 13 июля 2010

Это IS проблема с отложенным выполнением. Однако моя проблема связана с тем, что я не могу установить, ПОЧЕМУ это выполнение иногда откладывается, а не в других случаях.

Код:

IList<LineItem> freeFlatItems = new List<LineItem>();

if(QualifyFreeFlatShipping)
    freeFlatItems = lineItems.Where(l => l.FlatShippingRate != null).ToList();

decimal? freeFlatShippingTotal = freeFlatItems.Sum(l => l.FlatShippingRate);

var globalShippingPromos = _promoService.GetGlobalShippingPromos();

Проблема:

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

  1. Перед тем, как получить этот код, я проверил входные данные. Все предметы в lineItems. Каждый элемент имеет в качестве значения для .FlatShippingRate
  2. QualifyFreeFlatShipping is true
  3. Выполнение кода достигает строки linq в строке 4 (freeFlatItems = etc...)
  4. Значение freeFlatItems остается неизменным, так как выполнение продолжается до строки 6 (decimal? freeFlatShippingTotal = etc...)
  5. .Sum выполняется через пустой список.
  6. По достижении строки 8 (var globalShippingPromos = etc...) значение freeFlatItems окончательно обновляется до того, что должно быть . Однако ... сумма была получена с предыдущим значением, и итоговая стоимость доставки неверна.

Вопрос (ы):

  1. Почему это все еще откладывается? Я думал, .ToList() заставил выполнение linq сгенерировать IList<T>
  2. Почему это ведет себя по-разному в последовательной манере? (Мой тест всегда ведет себя так, производство работает нормально, этот код в LinqPad работает отлично). И прежде чем вы это предложите, я проверил, что мой тест составлен правильно. Как в тестовом коде, так и в первом шаге, проверяя входные данные в отладчике.

Ответы [ 2 ]

2 голосов
/ 16 сентября 2010

1.

Здесь нет отложенного выполнения. «Где» принудительно вызывается ToList (), а «Сумма» вычисляется немедленно и сохраняется в десятичном виде. Ошибка должна быть где-то еще

2

Когда вы вычисляете сумму во второй раз после строки 8, скажем с помощью:

decimal? freeFlatShippingTotal2 = freeFlatItems.Sum(l => l.FlatShippingRate);

вы тогда получаете правильное значение? Итак, freeFlatShippingTotal2! = FreeFlatShippingTotal?

0 голосов
/ 13 июля 2010

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

decimal freeFlatShippingTotal = 0.0m;
if(QualifyFreeFlatShipping)
    freeFlatShippingTotal = lineItems.Sum(l => l.FlatShippingRate ?? 0.0m);
...