我知道 C# 代码可以在运行时使用 C# 进行编译。然而,自从我几分钟前才读到它以来,我对此感到非常非常不稳定。通过例子我学得更好。所以告诉我。如果我想编译类似的东西:
// MapScript.CS
String[] LevelMap = {
"WWWWWWWWWWWWWWWWWWW",
"WGGGGGGGGGGGGGGGGGW",
"WGGGGGGGGGGGGGGGGGW",
"WWWWWWWWWWWWWWWWWWW" };
并在我的代码中使用这个数组,我该怎么做?
在伪代码中我想做这样的事情:
Open("MapScript.CS");
String[] levelMap = CompileArray("levelMap");
// use the array
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() );
您似乎想要编译 C# 代码,以便将文本 (C#) 文件中的字符串列表加载到字符串数组变量中。
您不需要 C# 编译器将文本文件中的字符串列表加载到内存中的数组中。 只需在文本文件中每行放入一个字符串,然后在代码中逐行读取文件,将每一行添加到
List<String>
。 完成后,list.ToArray()
将生成字符串数组。
您可以创建一个继承自
ILevel的类
CompiledLevel
,它提出了类型为 String[]
的静态属性 Level。
然后,在编译之前,创建一个假的
CompiledLevel.cs
文件,该文件是根据类模板构建的,其中填充了 LevelMap(wwwggg...)(某种串联)的内容。
编译后,调用编译类上的 Level 属性。
创建一个服务/工厂/任何让它变得花哨的东西:)