C# 中谓词参数的语法如何工作?
某些对象关系映射 (ORM) 框架(例如 LLBLGen)允许您为查询方法指定“谓词”参数,例如(稍微简化一下):
var entities = adapter.FetchEntities(EntityType.Employee,
EmployeeFields.Salary > 50000);
第二个参数在 C# 中的语法如何工作? 它看起来有点像 lambda 表达式,但它没有参数部分或“=>”。 它是什么? 可能需要乔恩·斯基特来做这件事。
Some Object Relational Mapping (ORM) frameworks (such as LLBLGen) allow you to specify "predicate" parameters to the query methods, such as (simplified a bit):
var entities = adapter.FetchEntities(EntityType.Employee,
EmployeeFields.Salary > 50000);
How does that 2nd parameter work syntactically in C#? It kind of looks like a lambda expression, but it doesn't have the parameter part or the "=>". What is it? May need Jon Skeet for this one.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果您重载了“
>
”运算符以在特殊的“SuperDatabaseMapField
”类型上返回某种谓词对象,则可以执行此类操作。也就是说,它在各方面似乎都比采用 lambda 表达式要差得多(如果需要的话还可以解析表达式树。)
If you overloaded the "
>
" operator to return some kind of predicate object on your special "SuperDatabaseMapField
" type, you could do such things.That said, it seems vastly inferior in every way to taking a lambda expression instead (and parsing an expression tree if you have to.)
我同意 mquander 的回答。 这种构造之所以有效,是因为编译器评估表达式的方式。 在本例中,对于 LLBLGen,第二个参数期望可以计算为布尔值(例如)。
运算符(+、-、***、/)只是编译器用来构建语法树的表达式,语法树用于验证左表达式和右表达式的某些组合在给定上下文(“+”)的情况下是否有效。 例如,
a
(字符串文字)+2.4
(浮点)在 C# 中显然无效,编译器通过验证表达式 (string) (operator_add) (浮动)。因此,为了实现像下面这样的奇怪场景:
有必要重载运算符(- 和 *** 和 +)以返回一个新的“谓词”对象。
最终这样的语句将被翻译成以下语法树(“()”中的项目是本答案中的表达式类型)
这是 lambda 表达式和流畅查询等内容如何工作的整体基础。 这一切都归结为表达式评估。
Lambda 表达式更具表现力,因为它们可以触及对象及其字段、属性和方法,并允许形成任意长度的语法树。
I agree with
mquander's
answer. The reason such a construct works is because of the way compilers evaluate expressions. In this case for LLBLGen, the second parameter expects something that can be evaluated to a boolean (for instance).Operators (+, -, ***, /) are merely expressions that the compiler uses to build syntax trees which it uses to validate if certain combinations of left and right expressions are valid given the context ("+"). For instance
a
(string literal) +2.4
(float) is obviously not valid in C#, and the compiler knows this from validating the expressions (string) (operator_add) (float).Therefore, in order to make an odd scenario like the following work:
it would be necessary to overload the operators (- and *** and +) to return a new "predicate" object.
Ultimately such a statement would be translated into the following syntax tree (items in "()" are expression types for the purpose of this answer)
This is the whole basis on how things like lambda expressions and fluent query works. It all boils down to expression evaluation.
Lambda expressions are more... expressive in that they can touch objects and their fields and properties and methods and allow an arbitrary length syntax tree to be formed.