首页 > C# > 为什么使用 Expression> 而不是 Func

为什么使用 Expression> 而不是 Func

上一篇 下一篇

我理解 lambda 和 和 代表。但表情
难倒了我。
FuncAction

在什么情况下你会使用一个而不是一个普通的旧?Expression<Func<T>>Func<T>

分割线

网友回答:

我正在添加一个菜鸟的答案,因为这些答案似乎超出了我的头脑,直到我意识到它是多么简单。有时,正是您对它复杂的期望使您无法“绕开它”。

我不需要了解其中的区别,直到我走进一个非常烦人的“错误”,试图一般使用 LINQ-to-SQL:

public IEnumerable<T> Get(Func<T, bool> conditionLambda){
  using(var db = new DbContext()){
    return db.Set<T>.Where(conditionLambda);
  }
}

这很好用,直到我开始在更大的数据集上获得 OutofMemoryExceptions。在 lambda 中设置断点让我意识到它正在逐个遍历表中的每一行,寻找与我的 lambda 条件匹配的匹配项。这让我难倒了一段时间,因为为什么它将我的数据表视为一个巨大的 IEnumerable,而不是像它应该的那样执行 LINQ to-SQL?它也在我的LINQ-to-MongoDb对应物中做了完全相同的事情。

修复只是变成 ,所以我用谷歌搜索了为什么它需要一个而不是 ,结束在这里。Func<T, bool>Expression<Func<T, bool>>ExpressionFunc

表达式只是将委托转换为有关自身的数据。所以变成类似“在左侧有一个.在右侧,你加 1 到它。就是这样。你现在可以回家了。它显然比这更有条理,但这本质上是一个表达式树的全部——没有什么可以包裹你的头。a => a + 1int a

理解了这一点,就很清楚为什么 LINQ-to-SQL 需要一个 ,而 a 是不够的。 它没有一种进入自己的方法,看看如何将其转换为 SQL/MongoDb/other 查询的细节。你看不到它是在做加法、乘法还是减法。您所能做的就是运行它。另一方面,允许您查看委托内部并查看它想要执行的所有操作。这使您能够将委托转换为所需的任何内容,例如 SQL 查询。 不起作用,因为我的 DbContext 对 lambda 表达式的内容视而不见。因此,它无法将 lambda 表达式转换为 SQL;但是,它做了下一个最好的事情,并通过表中的每一行迭代了该条件。ExpressionFuncFuncExpressionFunc

编辑:应约翰彼得的要求阐述我的最后一句话:

IQueryable 扩展了 IEnumerable,因此 IEnumerable 的方法如获取接受 .当你传递 an 时,你会保留一个 IQueryable,但是当你传递 a 时,你会回到基本的 IEnumerable,结果你会得到一个 IEnumerable。换句话说,您没有注意到您已将数据集转换为要迭代的列表,而不是要查询的内容。在你真正看到签名之前,很难注意到差异。Where()ExpressionExpressionFunc

分割线

网友回答:

当您想要将 lambda 表达式视为表达式树并查看它们内部而不是执行它们时。例如,LINQ to SQL 获取表达式并将其转换为等效的 SQL 语句并将其提交到服务器(而不是执行 lambda)。

从概念上讲,与 完全不同。 表示 a 它几乎是指向方法的指针,并表示 lambda 表达式的树数据结构。此树结构描述了 lambda 表达式的作用,而不是实际操作。它基本上保存有关表达式,变量,方法调用,…(例如,它保存诸如此lambda是某个常量+某些参数之类的信息)。您可以使用此说明将其转换为实际方法(使用 )或使用它执行其他操作(如 LINQ to SQL 示例)。将 lambda 视为匿名方法和表达式树的行为纯粹是编译时的事情。Expression<Func<T>>Func<T>Func<T>delegateExpression<Func<T>>Expression.Compile

Func<int> myFunc = () => 10; // similar to: int myAnonMethod() { return 10; }

将有效地编译为一个 IL 方法,该方法什么也不得到并返回 10。

Expression<Func<int>> myExpression = () => 10;

将转换为描述不获取参数并返回值 10 的表达式的数据结构:

虽然它们在编译时看起来相同,但编译器生成的内容完全不同

分割线

网友回答:

在选择表达式与 Func 时,一个极其重要的考虑因素是,IQueryable 提供程序(如 LINQ to Entities)可以“消化”您在表达式中传递的内容,但会忽略您在 Func 中传递的内容。我有两篇关于这个主题的博客文章:

有关表达式与 Func 与实体框架
以及爱上 LINQ 的更多信息 – 第 7 部分:表达式和函数(最后一部分)

模板简介:该模板名称为【为什么使用 Expression> 而不是 Func?】,大小是暂无信息,文档格式为.编程语言,推荐使用Sublime/Dreamweaver/HBuilder打开,作品中的图片,文字等数据均可修改,图片请在作品中选中图片替换即可,文字修改直接点击文字修改即可,您也可以新增或修改作品中的内容,该模板来自用户分享,如有侵权行为请联系网站客服处理。欢迎来懒人模板【C#】栏目查找您需要的精美模板。

相关搜索
  • 下载密码 lanrenmb
  • 下载次数 436次
  • 使用软件 Sublime/Dreamweaver/HBuilder
  • 文件格式 编程语言
  • 文件大小 暂无信息
  • 上传时间 02-21
  • 作者 网友投稿
  • 肖像权 人物画像及字体仅供参考
栏目分类 更多 >
热门推荐 更多 >
html5 微信模板 企业网站 自适应 单页式简历模板 微信文章 微信素材 微信公众平台 微信图片 响应式
您可能会喜欢的其他模板