丢弃 LINQ "from" 语句的行

Discard rows of a LINQ "from" statement

我正在使用 Sprache 库,它允许使用 LINQ 构建解析器。然而,有时我需要解析一些东西然后丢弃结果。例如:

from key in Identifier
from __ws1 in OptionalWhitespace
from __setter in PropertySetter
from __ws2 in OptionalWhitespace
from value in PropertyValue
select ...

我不需要前缀为__的三个变量中的任何一个,因此似乎没有必要用它们污染命名空间。

有什么方法可以执行 LINQ 查询并丢弃这三个结果吗?

由于对 Sprache 没有深入的了解,我已经超级简化了示例以理解问题域。

以多个 from 语句(使用 LinqPad)为例,我们只对 from 的值之一感兴趣。所以在这个任意的例子中,我们想知道人和蛋糕的所有组合,但只对蛋糕的名字感兴趣。

var people = new List<string> {
    "Billy", "Jimmy"
};

var cake = new List<string> {
    "Carrot Cake", "Chocolate Cake"
};

(from p in people
from c in cake
select new
{
    c
}).Dump();

多个 from 语句可以被认为是嵌套的 foreach 循环,最终成为交叉连接(如此处讨论LINQ Join with Multiple From Clauses

所以让我们假设这是 Sprache 作者的意图,如果我们尝试用流畅的语法重写它(如此处讨论:https://codeblog.jonskeet.uk/2011/01/28/reimplementing-linq-to-objects-part-41-how-query-expressions-work/),它最终会成为 SelectMany().

我们最终得到这样的结果:

people.SelectMany(p => cake, (p, c) => new { c }).Dump();

你仍然以 "person" 参数结束。

所以我建议,为了保持 Sprache 的意图,没有办法不使用 __ 语句。除非你自己构建表达式树,但我无法想象那会有成效。

在这种特殊情况下,您可以使用 Then 一次丢弃所有不相关的部分:

var parser =
    from key in Identifier
    from _ in OptionalWhitespace
        .Then(_ => PropertySetter)
        .Then(_ => OptionalWhitespace)
    from value in PropertyValue
    select new
    {
        key,
        value
    };

但如果不相关的部分不立即相互跟随,则在一般情况下无济于事。

Sprache 实现了 LINQ 查询方法,用于像解析器组合器这样的解析器函数的单子绑定。 (LINQ 可用于比查询 EF DbSets 更有趣的东西。) 遗憾的是,LINQ 查询范围变量(目前)不支持丢弃,因此您的“_”范围变量将在范围内发生冲突。当我在查询中有多个变量时,我通常会命名我不需要的范围变量,例如“_N”(其中 N 在 [1..] 中),并希望记住在它们得到支持时使用适当的丢弃。