Insert test for null in single LINQ expression

Let's start with a simple class of examples:

public class Foo { public DateTime Date { get; set; } public decimal Price { get; set; } } 

Then create a list:

 List<Foo> foos = new List<Foo>; 

I would like to return the formatted price or "N / A" of one item in the list based on the date, so for example, I could write:

 Foo foo = foos.FirstOrDefault(f => f.Date == DateTime.Today); string s = (foo != null) ? foo.Price.ToString("0.00") : "N/A"; 

I would like to combine the following two lines as shown below:

 string s = foos.FirstOrDefault(f => f.Date == DateTime.Today).Price.ToString("0.00") ?? "N/A"; 

However, this does not achieve what I want, because if (f => f.Date == DateTime.Today) does not return Foo, then a NullReferenceException is NullReferenceException .

Therefore, is it possible for LINQ to create only 1 instruction to return a formatted price or "N / A"?

+4
source share
3 answers

If you filter first and then select, you can use the zero coalescing operator ( ?? ) as follows:

 string price = foos.Where(f => f.Date == DateTime.Today) .Select(f => f.Price.ToString()) .FirstOrDefault() ?? "N/A"; 
+10
source

One way is to simply check if the FirstOrDefault result is null before calling ToString :

 var todayFoo = foos.FirstOrDefault(f => f.Date == DateTime.Today); var s = todayFoo != null ? todayFoo.Price.ToString("0.00") : "N/A"; 

Another way is to create an extension method for the coalescing operator, which the projection delegate will also accept, for example:

 public static class ObjectExt { public static T2 Coalesce<T1, T2>( this T1 obj, Func<T1, T2> projection, T2 defaultValue) { if (obj == null) return defaultValue; return projection(obj); } } 

And then name it like this:

 var s = foos .FirstOrDefault(f => f.Date == DateTime.Today) .Coalesce(t => t.Price.ToString("0.00"), "N/A"); 
+5
source

string s = foos.Where(f => f.Date == DateTime.Today).Select(f => f.Price.ToString("0.00")).FirstOrDefault();

+2
source

All Articles