在运行时编译C#数组并在代码中使用?

4

我知道可以使用C#在运行时编译代码。然而,由于我刚刚读到它,所以非常摇晃不定。我更喜欢通过示例来学习。告诉我。如果我想编译这样的东西:

// MapScript.CS
String[] LevelMap = {
"WWWWWWWWWWWWWWWWWWW",
"WGGGGGGGGGGGGGGGGGW",
"WGGGGGGGGGGGGGGGGGW",
"WWWWWWWWWWWWWWWWWWW" };

如果我想在代码中使用该数组,我应该如何操作呢?伪代码如下:
``` //定义数组 array = [value1, value2, value3, ...];
//调用数组元素 element = array[index]; ```
Open("MapScript.CS");
String[] levelMap = CompileArray("levelMap");
// use the array

2
你希望通过编译这个字符串数组实现什么目的?它将被编译成什么? - dthorpe
我真的不确定你的问题是关于什么的。是关于在运行时创建字符串数组吗?从文本文件中加载字符串怎么样? - Martin Liversage
在运行时将其读入已编译的数组中可能会更简单和不那么痛苦。 - Wug
一个只有数组的动态创建类可能是过于复杂化了...一个带有计算逻辑的数组的动态类编译进去...这可能是技术的一个很好的应用。 - Tim M.
3个回答

6
LINQ表达式树可能是实现这一目标最友好的方式,以下是一个示例: 你还可以使用OpCodes(OpCodes.Newarr)生成IL代码。如果你熟悉基于堆栈的编程,这也很容易(否则可能有挑战性)。
最后,你可以使用CodeDom(类似于你的伪代码),但是它虽然是最强大的工具,但对于快速动态方法来说不太理想。它需要文件系统权限和手动引用解决方案,因为你需要与编译器紧密合作。
下面是MSDN上的示例:
var ca1 = new CodeArrayCreateExpression("System.Int32", 10);                        
var cv1 = new CodeVariableDeclarationStatement("System.Int32[]", "x", ca1);

来源 - 使用代码对象模型创建数组

如果您想要一个纯的字符串编译,可以省略语句的面向对象处理,而是仅构建一个大字符串。例如:

var csc = new CSharpCodeProvider( new Dictionary<string, string>() { { "CompilerVersion", "v4.0" } } );
var cp = new CompilerParameters() {
    GenerateExecutable = false,
    OutputAssembly = outputAssemblyName,
    GenerateInMemory = true
};

cp.ReferencedAssemblies.Add( "mscorlib.dll" );
cp.ReferencedAssemblies.Add( "System.dll" );
cp.ReferencedAssemblies.Add( "System.Core.dll" );

StringBuilder sb = new StringBuilder();

// The string can contain any valid c# code, but remember to resolve your references

sb.Append( "namespace Foo{" );
sb.Append( "using System;" );
sb.Append( "public static class MyClass{");

// your specific scenario
sb.Append( @"public static readonly string[] LevelMap = {
    ""WWWWWWWWWWWWWWWWWWW"",
    ""WGGGGGGGGGGGGGGGGGW"",
    ""WGGGGGGGGGGGGGGGGGW"",
    ""WWWWWWWWWWWWWWWWWWW"" };" );

sb.Append( "}}" );

// "results" will usually contain very detailed error messages
var results = csc.CompileAssemblyFromSource( cp, sb.ToString() );

2

看起来您想编译C#代码,以便将文本(C#)文件中的字符串列表加载到字符串数组变量中。

您不需要C#编译器将字符串列表从文本文件加载到内存中的数组中。只需在文本文件中每行放置一个字符串,并在代码中逐行读取该文件,将每行添加到List<String>中。完成后,list.ToArray()将生成您的字符串数组。


0

您可以创建一个类CompiledLevel,该类继承自ILevel,提供了一个类型为String[]的静态属性Level

然后,在编译之前,从填充有LevelMap内容(wwwggg...)的类模板中创建一个假的CompiledLevel.cs文件(一种连接方式)。

编译完成后,在编译的类上调用Level属性。

创建一个服务/工厂/其他来使其更加美观 :)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接