问题 是否可以像LINQ一样创建C#语言修改?


我一直在寻找相当多的东西 Skeet先生关于如何重新实现LINQ的博客

特别是,他声明代码:

var list = (from person in people
        where person.FirstName.StartsWith("J")
        orderby person.Age
        select person.LastName)
       .ToList(); 

转换为LINQ库提供的扩展方法的方法:

people.Where(person => person.FirstName.StartsWith("J"))
  .OrderBy(person => person.Age)
  .Select(person => person.LastName) 

由编译器。

我的问题是,如何用图书馆给这些大人物留下足够的印象,让他们允许语言改变以支持图书馆?或者在LINQ出现之前这些词已经被保留了?


1629
2017-08-30 17:29


起源

成为Jon Skeet? - Dustin Davis
微软“大假发” 爱 饼干.... - FishBasketGordo
你意识到LINQ是由微软开发的,同一家公司指的是C#,.NET和CLR,对吧? - BoltClock♦
我不确定为什么关闭它。显然,OP无法说服编译器开发人员为他或她的库实现新语法,但这个问题很容易通过“编写在编译器之前运行的预处理器”来回答。 - David Brown
看到 stackoverflow.com/questions/5780648/... 对于规范的“为什么不添加语法”的答案。 - John Saunders


答案:


抓住Mono C#编译器 - 它是开源的,你可以做任何你想要的语言修改和.net支持,例如,使用枚举作为通用约束,创建返回值类型引用的方法(public ref int Max(ref int x, ref int y) { if (x>y) return ref x; else return ref y; }),具有保护或内部可见性等

当然,你正在创建一个不兼容的C#派生词,但是如果你把它推得足够硬,那么人们可能会喜欢它。

另一个选择:启动博客,为它提出一些非常好的用例,可能是.net语言的示例实现或使用自定义编译器,显示它解决了什么问题以及为什么这将是一个很大的胜利,证明了指定,设计,开发,测试和记录功能的成本。


9
2017-08-30 19:16



您无法通过更改编译器来执行所需操作。由于它只是将C#转换为CLR,因此您仍然受限于CLR的规则。您需要修改.NET框架本身 和 编译器。 - Stefan Steinegger
@Stefan,你可以“伪造”很多CLR不支持的东西。要么自己实现它们(比如C#闭包),要么假装它们确实存在,但不要将它们包含在生成的代码中(如F#度量单位或Java泛型)。 - svick
@Stefan:这就是我说的 - “你想要的修改和.net支持的”。所以,如果你想要“确定性终结”之类的东西,那么你当然不走运。但是.net支持C#不具备的大量功能。 - Michael Stum♦
@Michael:好的,对不起,没注意到这一点。 - Stefan Steinegger


我非常怀疑编译器开发人员会为任何库实现语法扩展。如果你真的想要语言级集成,你可以开发一个预处理器,将你的自定义语法转换为有效的C#。这基本上就是编译器对LINQ所做的事情(正如你在你的问题中指出的那样)。

当然,您会在Visual Studio中丢失自动完成和语法突出显示等内容,但可以通过扩展修复。


3
2017-08-30 19:00





有些语言允许扩展它们的语法和语义。离C#最近的是 Nemerle (它甚至支持C#的安全子集,你可以根据自己的喜好扩展它,但是,例如,几乎所有的Lisp都可以做到这一点。所以,如果你使用的语言足够强大,你就不需要“打动”任何人 - 任何库都可以为语言本身添加新的功能。

有传言称下一个C#也将提供一些基本的元编程支持,但我找不到任何具体细节。


1
2017-08-31 15:45



也很有趣。我想我必须尝试这个。 - user420667


这是可能的,但它很难,他们可能会重新实现这个想法,以更好地适应他们的语言结构。例如,新的异步功能类似于名为AsyncEnumerator的库,但它们正在构建更好地适应语言的所有内容。 LINQ的关键字未提前保留,但它们是上下文关键字,这意味着可以在LINQ上下文之外存在与此关键字匹配的标识符。当编译器检测到LINQ构造时,它进入LINQ模式,其中这些关键字是实际的保留字。


0
2017-08-30 19:18