元编程是否可以在C#中实现?

Bri*_*ndy 37 c# metaprogramming

特别是,是否可以在c#中编译时执行类似于此c ++代码的代码

template <int N>
struct Factorial 
{
    enum { value = N * Factorial<N - 1>::value };
};

template <>
struct Factorial<0> 
{
    enum { value = 1 };
};

// Factorial<4>::value == 24
// Factorial<0>::value == 1
void foo()
{
    int x = Factorial<4>::value; // == 24
    int y = Factorial<0>::value; // == 1
}
Run Code Online (Sandbox Code Playgroud)

Jac*_*all 31

不,C#语言不直接支持这种复杂性的元编程.但是,像@littlegeek所说,Visual Studio附带的文本模板转换工具包将允许您实现任何复杂性的代码生成.

  • @StanislavProkop我删除了断开的链接并将Scott Hanselman的文章提升为主要文章. (2认同)

Jon*_*rop 26

在.NET中可以进行元编程(参见编译器编译器,正则表达式,代码DOM,反射等),但C#不能进行模板元编程,因为它没有该语言功能.

  • +1用于简要而全面地回答问题的各个方面. (3认同)

Ira*_*ter 7

大多数人坚持尝试从他们喜欢的语言内部进行元编程.如果语言不能很好地支持元编程,那就行不通; 其他答案都观察到C#没有.

解决这个问题的方法是使用程序转换工具从语言 外部进行元编程.这些工具可以解析源代码,并对其进行任意转换(这就是元编程所做的事情),然后吐出修改后的程序.

如果您有一个可以解析任意语言的通用程序转换系统,那么您可以使用您喜欢的任何语言进行元编程.请参阅我们针对此类工具的DMS软件重新设计工具包,它具有适用于C,C++,Java,C#,COBOL,PHP和许多其他编程语言的强大前端,并已用于所有这些的元编程.

DMS之所以成功,是因为它提供了一个常规的方法和支持基础设施,可以完全访问作为AST的程序结构,并且在大多数情况下还提供了额外的数据,如符号表,类型信息,控制和数据流分析,这些都是进行复杂程序操作所必需的.

编辑(回应评论):可以应用DMS来实现OP在C#上的任务.

  • -1:答案很好,但它没有回答这个问题. (2认同)

小智 6

在讨论处理Java或.Net语言时的编译时,你必须小心.在这些语言中,你可以执行比C++更强大的元编程(在更广泛的意义上 - 反射 - ),因为"编译时间"(JIT)可以在"运行时间"之后被推迟;)


Bri*_*ian 5

不,C#中不可能进行元编程.


Han*_*ant 5

.NET 泛型和 C++ 模板之间的本质区别在于泛型是在运行时专门化的。模板在编译时扩展。泛型的动态行为使 Linq、表达式树、Type.MakeGenericType()、语言独立性和代码重用等成为可能。

但是这是有代价的,例如,您不能对泛型类型参数的值使用运算符。您不能在 C# 中编写 std::complex 类。并且没有编译时元编程。

  • 1) 重载运算符没有通用约束。因此你失去了编译时的安全性。2) 如果没有这些限制,则无法在专业化上选择用户定义的运算符。因此,您需要使用运行时方法生成,并且每当调用运算符时都会产生委托调用开销。3) 你不能表达类似“如果`T1`可以隐式转换为`T2`,那么`Complex&lt;T1&gt;`应该可以隐式转换为`Complex&lt;T2&gt;`”。 (3认同)