3

我正在考虑仅使用普通的 C#/.NET 4 语法来实现模板引擎,并具有静态类型的优势。

然后在该模板语言之上,我们可以创建领域特定语言(比如 HTML4、XHTML、HTML5、RSS、Atom、Multipart Emails 等)。

.NET 4 中最好的 DSL 之一(如果不是唯一的话)是SharpDOM。它实现了特定于 HTML 的 DSL。

看看 SharpDOM,我对使用 .NET (4) 可以做的事情印象深刻。

所以我相信在 .NET 4 中实现自定义 DSL 有一些不太知名的方法。可能不如 Ruby,但仍然如此。

所以我的问题是:可用于实现自定义 DSL 的 C# (4) 特定语法特性是什么?

我现在能想到的例子:

// HTML - doesn't look tooo readable :)
div(clas: "head",
  ul(clas: "menu", id: "main-menu", () => {
    foreach(var item in allItems) {
      li(item.Name)
    }
  }) // See how much noise it has with all the closing brackets?
)

// Plain text (Email or something) - probably too simple
Line("Dear {0}", user.Name);
Line("You have been kicked off from this site");

对我来说,很难想出噪音最少的语法。

请注意,我不是在谈论另一种语言(Boo、IronRuby 等),也不是在谈论不同的模板引擎(NHaml、Spark、StringTemplate 等)。

4

2 回答 2

2

您知道T4 模板吗?虽然它不允许您创建DSL,但一旦您有一个模型可供使用,它对于生成代码或其他基于文本的工件肯定是不错的。例如,TextTemplate1.tt:

<#@ template debug="false" hostspecific="false" language="C#" #>
<#@ output extension=".thml" #>
<#@ import namespace="System.Collections.Generic" #>

<div class="head">
    <ul class="menu" id="main-menu">
<#
foreach (var item in allItems)
{
#>
        <li><#= item.Name #></li>
<#
}
#>
    </ul>
</div>
<#+
public class DummyItem
{
    public string Name {get;set;}
}

public List<DummyItem> allItems = new List<DummyItem>
                                  {
                                      new DummyItem {Name="Name1"},
                                      new DummyItem {Name="Name2"},
                                  };
#>

这很快产生了:

<div class="head">
    <ul class="menu" id="main-menu">
        <li>Name1</li>
        <li>Name2</li>
    </ul>
</div>

显然,除了创建一个虚拟类之外,您还必须以其他方式将您的模型放入系统中!

于 2011-02-25T02:05:32.420 回答
1

我猜你对 Martin Fowlers DSL 书很熟悉,但如果不是一定要看看它。它不包含任何特定于 C# 4.0 的内容,但具有一些您可以使用的内部 DSL 的通用模式。还要看看泛型类型和类型推断在 C# 中是如何工作的,LINQ 可能是使用高级语言特性来实现 DSL 的一个很好的例子。在 LINQ 中的内容也应该是一些 AST 操作,您可能也会感兴趣。

于 2010-05-18T08:16:22.200 回答