using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.Emit;
using Microsoft.CodeAnalysis.Text;
using System.Collections.Generic;
public static byte[] bytes;
public static void Main()
public static class Class
public static void Method()
for(int i = 0; i <= 1000; i++)
string subfix = ""is Odd"";
Console.WriteLine(i + $"" {subfix}"");
dynamic assembly = VirtualCSharp.Compile(code);
assembly.GetType("X.Class").GetMethod("Method").Invoke(null,null);
public static class VirtualCSharp
public static dynamic Compile(string code)
Console.WriteLine("Compiling");
DateTime start = DateTime.Now;
var references = GetReferences();
var compilation = CreateCompilation(references,code);
var emit = EmitAssembly(compilation);
DisplayCompilationErrors(emit.emitResult);
var assembly = LoadAssembly(emit.assemblyStream);
Program.bytes = emit.assemblyStream.ToArray();
TimeSpan compileTime = DateTime.Now - start;
Console.WriteLine($"Compiling Finished, Took {compileTime.TotalSeconds}s.");
private static List<PortableExecutableReference> GetReferences()
Console.WriteLine("\tGetting Assembly References...");
var references = AppDomain.CurrentDomain.GetAssemblies()
.Where(a => !a.IsDynamic)
.Select(a => MetadataReference.CreateFromFile(a.Location))
Console.WriteLine($"\tGetted {references.Count} Assemblies");
private static CSharpCompilation CreateCompilation(List<PortableExecutableReference> references, string code)
Console.WriteLine("\tCreating Compilation...");
var compilation = CSharpCompilation.Create("DynamicAssembly")
.WithOptions(new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary))
.AddReferences(references)
.AddSyntaxTrees(SyntaxFactory.ParseSyntaxTree(SourceText.From(code)));
Console.WriteLine($"\tCompiled Source Code Of {code.Length} Bytes.");
private static EmitAssemblyOutput EmitAssembly(CSharpCompilation compilation)
Console.WriteLine("\tEmitting Assembly...");
var assemblyStream = new System.IO.MemoryStream();
EmitResult emitResult = compilation.Emit(assemblyStream);
Console.WriteLine("\tAssembly Emitted.");
return new EmitAssemblyOutput(assemblyStream, emitResult);
private static dynamic LoadAssembly(System.IO.MemoryStream assemblyStream)
Console.WriteLine("\tLoading Assembly...");
assemblyStream.Seek(0, System.IO.SeekOrigin.Begin);
var dynamicAssembly = System.Runtime.Loader.AssemblyLoadContext.Default.LoadFromStream(assemblyStream);
Console.WriteLine("\tAssembly Loaded.");
private static void DisplayCompilationErrors(EmitResult emitResult)
if(emitResult.Success) return;
foreach (var diagnostic in emitResult.Diagnostics)
Console.WriteLine(diagnostic);
public struct EmitAssemblyOutput
public System.IO.MemoryStream assemblyStream;
public EmitResult emitResult;
public EmitAssemblyOutput(System.IO.MemoryStream assemblyStream, EmitResult emitResult)
this.assemblyStream = assemblyStream;
this.emitResult = emitResult;