如何在linq where子句中使用带有泛型func lambda的表达式?

时间:2011-10-21 11:54:11

标签: c# linq lambda expression-trees

这就是我所拥有的

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

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

编译器抱怨(正确)它无法从对象转换为T.

我应该如何从那里开始?


解决方案

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

我的想法是将List作为IQueryable然后我可以Cast ...

5 个答案:

答案 0 :(得分:4)

使用 .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();
}

如果您不完全确定所有元素都是T类型,则可以使用.OfType<T>()代替(跳过无法转换的元素)

编辑当T为valuetype(struct)时,您还需要使用.OfType<T>()

修改由于您的评论提到了IQueryable,这可能有所帮助:

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

答案 1 :(得分:1)

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();
}

答案 2 :(得分:1)

好的,修好了:

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

我的想法是将List作为IQueryable然后我可以Cast ...

答案 3 :(得分:0)

可能是动态构建表达式然后编译它是一个更好的选择。这是一个样本:

Expression<Func<TestClass, bool>> query = LambdaBuilder.BuildQuery(queryItems);
Func<TestClass, bool> compiledExpression = query.Compile();
var results = data.Where(compiledExpression);

您可以阅读my article

答案 4 :(得分:0)

你真的需要这个论点是Expression&gt;?不是这应该做的伎俩:

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

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