【问题标题】:Is it possible to extend the Query-Keywords in C# / LINQ?是否可以在 C#/LINQ 中扩展查询关键字?
【发布时间】:2011-11-07 11:06:15
【问题描述】:

是否可以用自己的定义来扩展 Linq 的查询关键字(例如:select、where 等)?

代码示例使其更清晰:

System.Collections.Generic.List<string> aList = 
    new System.Collections.Generic.List<string> { "aa", "ab", "ba", "bb" };

// instead of
string firstString = (from item in aList
                      where item.StartsWith("a")
                      select item).First();

// would be nice
string firstString = from item in aList
                     where item.StartsWith("a")
                     selectFirst item;

// or something else
from item in aList
where item.StartsWith("a")
WriteLineToConsole item;

我认为这是不可能的,但仍然希望 ;)

【问题讨论】:

  • 您有什么特别的理由想要这样做吗?
  • 三个 400K+ 用户回答了您的问题。去,宰山羊!

标签: c# linq select


【解决方案1】:

实现此目的的一种方法是编写一个预处理器,它将您的自定义 LINQ 关键字转换为标准 LINQ 关键字,然后再将其提供给编译器。顺便说一句,这就是它与标准 LINQ 关键字一起工作的方式。预处理器将它们转换为普通的扩展方法(.Select、.Where、.GroupBy、...),然后将其提供给不理解这些关键字的编译器。

当然,这样做会失去 Intellisense,但这可以通过编写 Visual Studio 扩展来解决。不过对于这种糖来说可能需要做很多工作。

【讨论】:

  • 知道这是一个非常古老的问题,但是您是否设法对自定义关键字做些什么?
【解决方案2】:

不,在语言规范或任何当前的 C# 编译器中是不可能的。您在那里创建的任何东西都不再是(纯)C#。

【讨论】:

    【解决方案3】:

    您无法添加自己的上下文关键字,但您可以影响现有关键字的含义。

    例如这段代码:

    string firstString = (from item in aList
                          where item.StartsWith("a")
                          select item).First();
    

    被有效地预处理为:

    string firstString = aList.Where(item => item.StartsWith("a"))
                              .First();
    

    ...因此,如果您更改 WhereFirst 方法调用的含义,您可以影响行为。

    如果你有胃口,你可能想看看我不久前写的this Stack Overflow answer,它在某些情况下改变了LINQ to Entities 中where 的行为。这是邪恶的,邪恶的代码。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-19
      • 1970-01-01
      相关资源
      最近更新 更多