Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cast an Expression

I have the following:

class Base
class Derived : Base
IQueryable<Derived> queryable = ???
Expression<Func<Base, bool>> filter = ???

I want to filter the queryable with the expression, and get back an IQueryable<Derived>.

However, Expression is invariant. That means that queryable.Where(filter) gets inferred to be Where(this IQueryable<Base>, Expression<Func<Base, bool>>), and returns IQueryable<Base> rather than IQueryable<Derived>.

C# doesn't allow for filter to be cast to Expression<Func<Derived, bool>>, and a cast of the IQueryable<Base> returned by Where to IQueryable<Derived> fails at runtime.

What is the best way around this?

like image 228
Martijn Avatar asked Feb 17 '26 05:02

Martijn


1 Answers

The pragmatic fix is:

var result = queryable.Where(filter).Cast<Derived>();

You could also do it by rewriting the expression tree, but... it doesn't seem worthwhile. But it works:

var typed = Expression.Lambda<Func<Derived, bool>>(
        filter.Body, filter.Parameters);
var result = queryable.Where(typed); // IQueryable<Derived>
like image 136
Marc Gravell Avatar answered Feb 18 '26 19:02

Marc Gravell