How to use an expression with a generic func lambda in a linq where clause?

c# expression-trees lambda linq

Question

Here's what I have

private readonly Dictionary<Type, List<object>> _cache;

public IList<T> Get<T> (Expression<Func<T, bool>> criteria)
{
    return _cache[typeof(T)].Where (criteria);
}

The compiler complains (rightly) that it cannot convert from object to T.

How should I proceed from there?


Solution

return _cached[type].AsQueryable().Cast<T>().Where (criteria).ToList()

The idea is to have the List as an IQueryable and then I could Cast...

Accepted Answer

Use the .Cast<>() Extension Method:

private readonly Dictionary<Type, List<object>> _cache;

public IList<T> Get<T> (Expression<Func<T, bool>> criteria)
{
    return _cache[typeof(T)].Cast<T>().Where (criteria).ToList();
}

If you aren't absolutely sure that all elements are of type T, you can use .OfType<T>() instead (which skips elements that cannot be cast)

Edit You'll also need to use .OfType<T>() when T is a valuetype (struct).

Edit Since your comment mentioned IQueryable, this could help:

return _cache[typeof(T)].AsQueryable().Cast<T>().Where (criteria).ToList();

Popular Answer

Ok, fixed it:

return _cached[type].AsQueryable().Cast<T>().Where (criteria).ToList()

The idea is to have the List as an IQueryable and then I could Cast...



Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Is this KB legal? Yes, learn why
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Is this KB legal? Yes, learn why