App*_*ker 4 c# compiler-construction runtime compilation
我知道C#代码可以在运行时使用C#编译.但是,因为我几分钟之前就读过它,所以我非常不稳定.我通过例子学到了很多东西.所以告诉我.如果我想编译类似的东西:
// MapScript.CS
String[] LevelMap = {
"WWWWWWWWWWWWWWWWWWW",
"WGGGGGGGGGGGGGGGGGW",
"WGGGGGGGGGGGGGGGGGW",
"WWWWWWWWWWWWWWWWWWW" };
Run Code Online (Sandbox Code Playgroud)
并在我的代码中使用此数组,我该怎么做呢?
在伪代码中我想做这样的事情:
Open("MapScript.CS");
String[] levelMap = CompileArray("levelMap");
// use the array
Run Code Online (Sandbox Code Playgroud)
LINQ表达式树可能是最友好的方式:也许类似于:
您还可以使用OpCodes(OpCodes.Newarr)生成IL .如果您对基于堆栈的编程感到满意,则很容易(否则,可能具有挑战性).
最后,您可以使用CodeDom(您的伪代码类似),但是 - 虽然是最强大的工具 - 它不太适合快速动态方法.由于您正在与编译器密切合作,因此它需要文件系统权限和手动参考解析.
来自MSDN的样本
var ca1 = new CodeArrayCreateExpression("System.Int32", 10);
var cv1 = new CodeVariableDeclarationStatement("System.Int32[]", "x", ca1);
Run Code Online (Sandbox Code Playgroud)
如果你想要一个字符串的直接原始编译,你可以省略面向对象的语句处理,而只是构建一个大字符串.就像是:
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() );
Run Code Online (Sandbox Code Playgroud)