2

I'm getting an error System.ArgumentNullException: Value cannot be null. on the following:

 foreach (var pmt in payment.NewInvoiceViewModels
   .Where(x => x.PaymentReceived != 0) ?? 
    Enumerable.Empty<NewInvoiceViewModel>())

All I'm trying to do is check of payment.NewInvoiceViewModels is null before I iterate over it (if it is null, it causes an error).

Is there a better way of achieving this?

Mark
  • 7,778
  • 24
  • 89
  • 147
  • Your approach is correct. You can however write a generic extension method to improve it. http://stackoverflow.com/questions/11734380/check-for-null-in-foreach-loop – emre nevayeshirazi Sep 26 '13 at 13:36
  • Hi Emrie - thanks - I thought it was correct, but if the object is empty, I get the Value cannot be null error - that's what I'm trying to get around. The link to the other question, is what I'm doing (I believe). Thanks, Mark – Mark Sep 26 '13 at 13:38
  • 1
    @emrenevayeshirazi: No, the approach is most definitely *not* correct at the moment. Calling `Enumerable.Where(null, predicate)` will throw an exception - just as the OP is reporting. – Jon Skeet Sep 26 '13 at 13:40

2 Answers2

9

You've got the null-coalescing operator in the wrong place - currently you're calling Where on payment.NewInvoiceModels unconditionally and then checking whether the result will be null... it never will be (Where simply doesn't return null). You potentially want:

foreach (var pmt in (payment.NewInvoiceViewModels ?? 
                     Enumerable.Empty<NewInvoiceViewModel>())
                   .Where(x => x.PaymentReceived != 0))

Personally I'd extract this out though:

var allModels = payment.NewInvoiceViewModels ?? 
                     Enumerable.Empty<NewInvoiceViewModel>();

foreach (var pmt in allModels.Where(x => x.PaymentReceived != 0))

Or perhaps introduce an extension method:

public static IEnumerable<T> NullToEmpty(this IEnumerable<T> source)
{
    return source ?? Enumerable.Empty<T>();
}

Then:

foreach (var pmt in payment.NewInvoiceViewModels
                           .NullToEmpty()
                           .Where(x => x.PaymentReceived != 0))
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Perfect - thank you - I'll mark as the answer as soon as SO allows (6 mins) - cheers, Mark – Mark Sep 26 '13 at 13:41
3

Do you want something like this

if(payment.NewInvoiceViewModels!=null)
{
  foreach (var pmt in payment.NewInvoiceViewModels
   .Where(x => x.PaymentReceived != 0) ?? 
    Enumerable.Empty<NewInvoiceViewModel>())
}
Sachin
  • 40,216
  • 7
  • 90
  • 102