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

发布于 2024-12-11 08:06:35 字数 460 浏览 0 评论 0原文

这是我所拥有的

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

这个想法是将列表作为 IQueryable,然后我可以投射...

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...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

双手揣兜 2024-12-18 08:06:35

使用.Cast<>()扩展方法

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()代替(它会跳过不能的元素)是cast)

编辑 当 T 是值类型(结构)时,您还需要使用.OfType()

编辑由于您的评论提到了 IQueryable,这可能会有所帮助:

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

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();
人海汹涌 2024-12-18 08:06:35
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();
}
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();
}
月下凄凉 2024-12-18 08:06:35

好的,修复了它:

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

想法是将列表作为 IQueryable,然后我可以投射...

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...

哭了丶谁疼 2024-12-18 08:06:35

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

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

您可以阅读 我的文章

may be building the expression dynamically and then compile it is a better option. here is a sample:

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

You may read my article on it

浮华 2024-12-18 08:06:35

您真的需要将参数设为 Expression> 吗?当然,这应该可以解决问题:

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

Do you really need the argument to be of Expression>? Of not this should do the trick:

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();
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文