4

I know C# code can be compiled at runtime using C#. However I'm very very shaky at it since I just read about it a few minutes ago. I learn a lot better by examples. So tell me. If I want to compile something like:

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

and use this array in my code, how would I go about it?

In pseudocode I want to do something like this:

Open("MapScript.CS");
String[] levelMap = CompileArray("levelMap");
// use the array
Community
  • 1
  • 1
ApprenticeHacker
  • 21,351
  • 27
  • 103
  • 153
  • 2
    What do you hope to achieve by compiling this string array? And what would it be compiled into? – dthorpe Jul 31 '12 at 20:58
  • I'm really not sure what your question is about. Is it about creating string arrays at run-time? How about loading the strings from a text file? – Martin Liversage Jul 31 '12 at 21:00
  • It would probably be much less complicated and painful to just read it into an already compiled array at runtime. – Wug Jul 31 '12 at 21:00
  • A dynamically created class with just an array is probably an overcomplication...a dynamic class with an array that has calculated logic about that array compiled into it...that could be a great use of the technology. – Tim M. Jul 31 '12 at 21:25

3 Answers3

6

LINQ Expression trees are probably the friendliest way of doing this: Perhaps something like:

You can also generate the IL using OpCodes (OpCodes.Newarr). Easy if you are comfortable with stack-based programming (otherwise, can be challenging).

Lastly, you can use the CodeDom (which your pseudocode resembles), but--while the most powerful tool--it is less ideal for quick dynamic methods. It requires file system permissions and manual reference resolution since you are working closely with the compiler.

Sample from MSDN

var ca1 = new CodeArrayCreateExpression("System.Int32", 10);                        
var cv1 = new CodeVariableDeclarationStatement("System.Int32[]", "x", ca1);

Source - Creating Arrays with the Code DOM

If you want a straight up raw compile of a string, you can omit the object-oriented treatment of the statements and instead just build a big string. Something like:

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() );
Tim M.
  • 53,671
  • 14
  • 120
  • 163
2

It appears that you are wanting to compile C# code in order to load a list of strings in a text (C#) file into a string array variable.

You don't need a c# compiler to load a list of strings from a text file into an array in memory. Just put one string per line in your text file, and read the file line by line in your code, adding each line to a List<String>. When you're done, list.ToArray() will produce your array of strings.

dthorpe
  • 35,318
  • 5
  • 75
  • 119
0

You can create a class CompiledLevel that inherits from ILevel which proposes a static property Level of type String[].

Then, before compiling, create a fake CompiledLevel.cs file built from a template of class filled with content of LevelMap (wwwggg...) (sort of concatenation).

One compiled, call Level property on the compiled class.

Create a service/factory/whatever to make it fancy :)

Francois
  • 10,730
  • 7
  • 47
  • 80