2011-08-31 56 views
7

是否可以使用自己的定义扩展Linq的查询关键字(如:select,where等)?是否可以在C#/ LINQ中扩展查询关键字?

Codeexample这样可以很清楚:

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; 

我认为这是不可能的,但仍然希望;)来实现,这将是写一个预处理器,这将改变您的自定义

+0

任何特定的原因,你为什么要这样做? – AakashM

+0

三位400K +用户回答了你的问题。去吧,宰一只山羊! – dotNET

回答

6

的一种方式在将LINQ关键字提供给编译器之前,将它们转换为标准LINQ关键字。顺便说一下,它是如何与标准的LINQ关键字一起工作的。预处理器将它们转换为正常的扩展方法(.Select,.Where,.GroupBy,...),然后将其提供给不理解这些关键字的编译器。

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

+1

你能为这个扩展提供一些起点吗? – Matthias

+0

知道这是一个非常古老的问题,但你有没有设法做一些关于自定义关键字? –

4

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

6

您不能添加您自己的上下文关键字,但您可以影响现有的关键字。

例如,下面的代码:

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的行为。这是邪恶的,但邪恶的代码。