Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Lambda vs LINQ- "Expression is always false"

I have the following code:

var thing = (from t in things
             where t.Type == 1 && t.IsActive
             select t).SingleOrDefault();

if (thing == null)
{
    // throw exception
}

things is a collection of Entity Framework Self-Tracking Entities

This works nicely, however I want to use a Lambda expression instead and changed the LINQ to this:

var thing = things.Select(t => t.Type == 1 && t.IsActive).SingleOrDefault();

Now Resharper is telling me Expression is always false for (thing == null).

What have I missed?

like image 459
Shevek Avatar asked Jun 22 '11 09:06

Shevek


1 Answers

You want:

var thing = things.Where(t => t.Type == 1 && t.IsActive).SingleOrDefault();

Select performs a projection (converting the type of the IEnumerable from IEnumerable<Thing> to IEnumerable<bool> with values true if t.Type == 1 && t.IsActive == true, otherwise false), then the SingleOrDefault returns either the only bool in this sequence, or the default value of a bool which is false if the sequence is empty. This can never be null since bool is not a reference type.

Where performs a filtering action (pulling out only those objects that meet a given criterion - in this case only selecting those where Type is 1 and IsActive is true), leaving the type of the IEnumerable as IEnumerable<Thing>. Assuming Thing is a class, the SingleOrDefault will return the only item in the sequence or null.

In either case, SingleOrDefault will throw an exception if the sequence contains more than one item (which is far more likely in the Select version!).

like image 68
Jackson Pope Avatar answered Sep 19 '22 06:09

Jackson Pope