在 C# 中可以进行元编程吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/237326/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 19:19:35  来源:igfitidea点击:

Is metaprogramming possible in C#?

c#metaprogramming

提问by Brian R. Bondy

In particular, would it be possible to have code similar to this c++ code executed at compile time in c#?

特别是,是否有可能在 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
}

采纳答案by Jacob Krall

No, metaprogramming of this complexity is not supported directly by the C# language. However, like @littlegeeksaid, the Text Template Transformation Toolkitincluded with Visual Studio will allow you to achieve code generation of any complexity.

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

回答by Brian

No, metaprogramming is not possible in C#.

不,元编程在 C# 中是不可能的。

回答by JaredPar

To a verylimited extent, C# something that could be interpreted as meta-programming. But really it's nothing more than overload resolution. It's a real stretch to call it meta programming.

非常有限的程度上,C# 可以解释为元编程。但实际上它只不过是重载决议。将其称为元编程是一种真正的延伸。

Example:

例子:

static string SomeFunc<T>(T value) {
    return "Generic";
}
static string SomeFunc(int value) {
    return "Non-Generic";
}

static void Example() {
    SomeFunc(42);           // Non-Generic
    SomeFunc((object)42);   // Generic
}

回答by Hans Passant

The essential difference between .NET Generics and C++ Templates is that generics are specialized at runtime. Templates are expanded at compile time. The dynamic behavior of generics makes things like Linq, expression trees, Type.MakeGenericType(), language independence and code re-use possible.

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

But there is a price, you can't for example use operators on values of the generic type argument. You can't write a std::complex class in C#. And no compile-time metaprogramming.

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

回答by thAAAnos

You must be carefull when talking about compile-time when dealing with Java or .Net languages. In those languages you can perform more powerfull metaprogamming (in the broader sense - reflection- ) than C++ due to the fact that "compilation time" (JIT) can be postponed after "run time" ;)

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

回答by ?zgür

It is going to be possible. Watch Anders Hejlsberg's The Future of C#talk.

这将是可能的。观看 Anders Hejlsberg 的 “C# 的未来”演讲。

回答by Ira Baxter

Most people insist on trying to metaprogram from inside their favorite language. That doesn't work if the language doesn't support metaprogramming well; other answers have observed that C# does not.

大多数人坚持尝试从他们最喜欢的语言内部进行元编程。如果语言不能很好地支持元编程,那将不起作用;其他答案已经观察到 C# 没有。

A way around this is to do metaprogramming from outsidethe language, using program transformation tools. Such tools can parse source code, and carry out arbitrary transformations on it (that's what metaprogramming does anyway) and then spit out the revised program.

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

If you have a general purpose program transformation system, that can parse arbitrary languages, you can then do metaprogramming on/with whatever language you like. See our DMS Software Reengineering Toolkitfor such a tool, that have robust front ends for C, C++, Java, C#, COBOL, PHP and a number of other programming langauges, and has been used for metaprogramming on all of these.

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

DMS succeeds because it provides a regular method and support infrastructure for complete access to the program structure as ASTs, and in most cases additional data such a symbol tables, type information, control and data flow analysis, all necessary to do sophisticated program manipulation.

DMS 之所以成功,是因为它提供了一种常规方法和支持基础结构,用于完全访问程序结构,如 AST,在大多数情况下,还提供附加数据,如符号表、类型信息、控制和数据流分析,所有这些都是进行复杂程序操作所必需的。

EDIT (in response to comment): One could apply DMS to implement the OP's task on C#.

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

回答by Jon Harrop

Metaprogramming is possible in .NET (see compiler compilers, regular expressions, code DOM, reflection etc.) but C# is not capable of templatemetaprogramming because it does not have that language feature.

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

回答by piojo

Not in the way you're asking, but you can use some of the old C++ tricks to generate classes whose traits are specified statically:

不是你问的那样,但你可以使用一些旧的 C++ 技巧来生成静态指定特征的类:

abstract class Integer
{
    public abstract int Get { get; }
}

public class One : Integer { public override int Get { return 1; } } }
public class Two : Integer { public override int Get { return 2; } } }
public class Three : Integer { public override int Get { return 3; } } }

public class FixedStorage<T, N> where N : Integer, new()
{
    T[] storage;
    public FixedStorage()
    {
        storage = new T[new N().Get];
    }
    public T Get(int i)
    {
        return storage[i];
    }
}

Using this, you could define spatial classes:

使用它,您可以定义空间类:

public class Vector3 : FixedStorage<float, Three> {}
public class Vector2 : FixedStorage<float, Two> {}
public class GridCell : FixedStorage<int, Two> {}

I use this technique in a library that has a lot of subclasses, where adding a new data member requires a lot of boilerplate.

我在一个有很多子类的库中使用这种技术,在那里添加一个新的数据成员需要很多样板。