views:

61

answers:

2

This IS a delayed execution problem. However, my issue stems from the fact that I cannot ascertain WHY this execution is delayed sometimes, and not other times.

Code:

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();

Problem:

This code is in production, and works as expected. I recently make changese elsewhere and found that this test was not working in our unit testing. When I step through this function the following happens:

  1. Before reaching this code, I verified the input data. All items in lineItems. Each Item has as value for .FlatShippingRate
  2. QualifyFreeFlatShipping is true
  3. Code Execution reaches the linq statment on line 4 (freeFlatItems = etc...)
  4. Value of freeFlatItems remains unchanged as execution continues to line 6 (decimal? freeFlatShippingTotal = etc...)
  5. .Sum is executed across an empty list.
  6. Upon reaching line 8 (var globalShippingPromos = etc...) the value of freeFlatItems finally updates to what it should be. However... sum was ran on the previous value, and my shipping total is incorrect.

The Question(s):

  1. Why is this still being delayed? I thought .ToList() forced the execution of the linq to generate the IList<T>
  2. Why does this behave differently in a consistant manner? (My Test always behaves this way, production works fine, this code in LinqPad works fine). And before you suggest it, I have validated my test is built up correctly. Both in the test code and in step one above by validating the input data in the debugger.
A: 

I don't think this is an issue with delayed execution. But I can suggest a cleaner way for the code to be written.

decimal freeFlatShippingTotal = 0.0m;
if(QualifyFreeFlatShipping)
    freeFlatShippingTotal = lineItems.Sum(l => l.FlatShippingRate ?? 0.0m);
ChaosPandion
Other code further down needs the list of freeFlat items.
Aren
+1  A: 

1.

There is no delayed execution here. The "Where" is forced by ToList(), and the "Sum" is evaluated immediately and stored in the decimal. The error has to be somewhere else

2.

When you evaluate the sum a second time after line 8, lets say with:

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

do you then get the correct value? So, freeFlatShippingTotal2 != freeFlatShippingTotal ?

Christian
Oh wow, thank you for taking the time to answer. This question however is 2 months old, I unfortunately don't remember much about what happened. I think I re-factored some stuff and approached it completely different to get around this. I'll give you +1 for taking the time so long after though :)
Aren
I don't know how I found this question, but I did not realize it was so old ;-) Thanks!
Christian