3

I have a Func defined as follows:

Func<Foo, bool> IsSuperhero = x => x.WearsUnderpantsOutsideTrousers;

I can query IEnumerables like this:

IEnumerable<Foo> foos = GetAllMyFoos();
var superFoos = foos.Where(IsSuperhero);

But when I try to supply the same Func to the Where method of an IQueryable, I get:

'Cannot convert source type System.Collections.Generic.IEnumerable to System.Linq.IQueryable.'

What's going on? How can I define a Func which will work as a specification for both IEnumerable and IQueryable?

David
  • 15,750
  • 22
  • 90
  • 150

1 Answers1

3

IQueryable's LINQ methods take Expression Trees, not normal delegates.

Therefore, you need to change your func variable to an Expression<Func<Foo, bool>>, like this:

Expression<Func<Foo, bool>> IsSuperhero = x => x.WearsUnderpantsOutsideTrousers;

To use the same variable with an IEnumerable<T>, you'll need to call AsQueryable() or Compile(), like this:

IQueryable<Foo> superFoos = foos.AsQueryable().Where(IsSuperhero);
IEnumerable<Foo> superFoos = foos.Where(IsSuperhero.Compile());
SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
  • But then I can't query IEnumerables with it!!! Surely there must be a way I can use the same specification with both? – David Aug 19 '10 at 15:14
  • @David: This behavior is necessary. `IQueryable` is meant for things like LINQ to SQL, which need to find out what the delegate does. This is not possible with a normal delegate, so they must take an `Expression`. – SLaks Aug 19 '10 at 15:20
  • Wow! I think I'm a long way from understanding that, but thanks for the pointer! :) – David Aug 19 '10 at 15:30
  • @David, it's worth learning more about, as expression trees are very, very cool. They encode information about what the expression _means_ rather than simply resulting in code that performs the function. Systems can make good use of this information to do fun, clever things like turning a strongly-typed .NET expression into a standard SQL query. – Dan Bryant Aug 19 '10 at 15:38
  • Thanks for that. I'm aware that they are used to convert a set of criteria into another form (e.g. a SQL or LDAP query), but way in which this is done is, for me, in a distant, misty land full of magic. But that may not always be the case! – David Aug 19 '10 at 15:43
  • Thanks everyone for your input. This has been a very educational post for me. – David Aug 19 '10 at 15:44