我如何制作自己的Linq条款?

时间:2009-07-13 23:20:06

标签: c# .net linq .net-3.5

有没有办法可以创建自己的Linq条款?我一直在研究扩展方法,这不是我想要的。

我在想像where,select或from子句。我想使用像我这样的代码

var blah = from bleep in bloops
           where bleep == razzie
           myclause bleep.property
           select bleep;

5 个答案:

答案 0 :(得分:4)

您无法更改编译器解释查询语句的方式。这些被称为查询理解 - 并且用于翻译它们的规则直接构建在C#编译器中。每个查询都被转换为适当的调用序列,进入Linq库中的扩展方法。

如果你使用像Reflector这样的工具,你会看到相应的扩展方法调用序列,这些表达式被翻译成。

查询理解规则完整记录在C# 3.0 specification

虽然我同意某些特定情况可能有助于扩展语言中的查询语法,但我怀疑它需要大量复杂的编译时处理才能将它们转换为适当的函数调用语法。我不认为在大多数情况下,只是为特殊情况注入处理而不影响整个表达式的转换是很容易的。

与此同时,要意识到您可以使用链接和常规扩展方法来扩展Linq的功能。

答案 1 :(得分:2)

为此,您需要访问C#编译器源代码。我会坚持使用Extension方法。如果您有Reflector的副本,则可以查看System.Data.Linq,并查看原始扩展方法是如何编写的。

答案 2 :(得分:0)

我不明白为什么你不能使用扩展方法。使用上面的查询,您可以将它从您拥有的内容转换为类似的内容:

var blah = (from bleep in bloops
           where bleep == razzie
           select bleep).myclause(bleep.property);

答案 3 :(得分:0)

这种语法只是一些糖......

var blah = bloops.Where( b => b == razzie );

那是不可扩展的。

你当然可以添加你自己的条款(只是扩展方法),你只是没有合成糖。

答案 4 :(得分:0)

这在C#中是不可能的,但是如果你真的想自己添加语法,你可以编写一个包含额外查询理解关键字的C#预编译器。要以与C#相同的方式实现它(如在the specification中),您将搜索一个例如有效的 MyClause() 扩展方法,用于返回类型源对象或调用链中的上一个返回类型,例如 IEnumerable<T>

你的例子:

var blah = from bleep in bloops
           where bleep == razzie
           myclause bleep.property
           select bleep;

会变成:

var blah = bloops.Where(bleep => bleep==razzie)
                 .MyClause(bleep => bleep.property)
                 .Select(bleep => bleep);