在C# / LINQ中是否可以扩展查询关键字?

8

是否可以扩展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;

我认为这不可能,但仍然抱有希望 ;)


你为什么想要这样做? - AakashM
三位拥有超过400K用户的人回答了你的问题。快去宰一只山羊庆祝吧! - dotNET
3个回答

8

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

例如,这段代码:

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

被有效的预处理成:

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

...所以,如果你改变那些WhereFirst方法调用的含义,就可以影响行为。

如果你有信心,你可能想看看我一段时间前写的这个Stack Overflow答案,它会在某些情况下改变LINQ到Entities中where的行为。但是这是非常难懂的代码。


6

实现这一目标的方法之一是编写一个预处理器,将您的自定义LINQ关键字转换为标准的LINQ关键字,然后再将其馈送给编译器。实际上,标准LINQ关键字就是这样处理的。预处理器将它们转换为正常的扩展方法(.Select、.Where、.GroupBy等),然后将其馈送给编译器,而编译器不理解这些关键字。

当然,通过这种方式,您将失去智能提示,但可以通过编写Visual Studio扩展来解决此问题。不过,为了这个语法糖,可能需要相当多的工作。


知道这是一个非常老的问题,但你是否成功处理了自定义关键字? - P. Waksman

4

不,根据语言规范和任何现有的C#编译器来看,这是不可能实现的。你所创建的任何东西都将不再是(纯粹的)C#。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接