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

ger*_*per 7 c# linq select

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

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;
Run Code Online (Sandbox Code Playgroud)

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

Jon*_*eet 7

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

例如,这段代码:

string firstString = (from item in aList
                      where item.StartsWith("a")
                      select item).First();
Run Code Online (Sandbox Code Playgroud)

有效地预处理:

string firstString = aList.Where(item => item.StartsWith("a"))
                          .First();
Run Code Online (Sandbox Code Playgroud)

...所以如果你改变那些Where和First方法调用的意思,你可以影响行为.

如果你有胃口,你可能想看看我刚才写的这个Stack Overflow回答,它where在某些情况下改变了LINQ to Entities 的行为.虽然它是邪恶的,邪恶的代码.


Dar*_*rov 6

实现这一目标的一种方法是编写一个预处理器,它将自定义LINQ关键字转换为标准LINQ关键字,然后再将其提供给编译器.顺便说一下它是如何使用标准LINQ关键字的.预处理器将它们转换为普通的扩展方法(.Select,.Where,.GroupBy,...),然后将其提供给不理解这些关键字的编译器.

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