在运行时编译C#数组并在代码中使用它?
我知道C#代码可以在运行时使用C#编译 。 但是,因为我几分钟前刚读过这篇文章,所以我非常不满意。 我通过例子学到了很多东西。 所以告诉我。 如果我想编译类似的东西:
// MapScript.CS String[] LevelMap = { "WWWWWWWWWWWWWWWWWWW", "WGGGGGGGGGGGGGGGGGW", "WGGGGGGGGGGGGGGGGGW", "WWWWWWWWWWWWWWWWWWW" };
并在我的代码中使用此数组,我该怎么做呢?
在伪代码中我想做这样的事情:
Open("MapScript.CS"); String[] levelMap = CompileArray("levelMap"); // use the array
LINQ表达式树可能是最友好的方式:也许类似于:
- http://msdn.microsoft.com/en-us/library/system.linq.expressions.newarrayexpression.aspx
- http://msdn.microsoft.com/en-us/library/bb357903.aspx
您还可以使用OpCodes( OpCodes.Newarr )生成IL。 如果您对基于堆栈的编程感到满意,则很容易(否则,可能具有挑战性)。
最后,您可以使用CodeDom(您的伪代码类似),但是 – 虽然是最强大的工具 – 它不太适合快速动态方法。 由于您正在与编译器密切合作,因此它需要文件系统权限和手动参考解析。
来自MSDN的样本
var ca1 = new CodeArrayCreateExpression("System.Int32", 10); var cv1 = new CodeVariableDeclarationStatement("System.Int32[]", "x", ca1);
Source – 使用Code DOM创建数组
如果你想要一个字符串的直接原始编译,你可以省略语句的面向对象处理,而只是构建一个大字符串。 就像是:
var csc = new CSharpCodeProvider( new Dictionary() { { "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#)文件中的字符串列表加载到字符串数组变量中。
您不需要ac#编译器将文本文件中的字符串列表加载到内存中的数组中。 只需在文本文件中每行放一个字符串,然后在代码中逐行读取文件,将每行添加到List
。 完成后, list.ToArray()
将生成您的字符串数组。
您可以创建一个inheritance自ILevel的 CompiledLevel
类,它提出类型为String[]
的静态属性Level 。
然后,在编译之前,创建一个伪造的CompiledLevel.cs
文件,该文件是从一个类的模板构建的,该模板填充了LevelMap的内容(wwwggg …)(连接类)。
一个已编译的,在已编译的类上调用Level属性。
创建一个服务/工厂/任何使它看起来很棒:)