2012-09-28 29 views
6

Estoy tratando de escribir una aplicación de enseñanza C# interactiva, donde el usuario puede experimentar/cambiar ejemplos de código y ver qué sucede (algo así como jsfiddle).Ejecutando un mini-programa en Mono.Csharp

He encontrado muchos ejemplos para expresiones pequeñas o usos similares a REPL de Mono.Csharp como compilador de tiempo de ejecución, pero no puedo encontrar un ejemplo donde se ejecuta un "mini programa".

Aquí está mi código de juguete hasta ahora (una acción de MVC). El parámetro "código" se publica directamente desde un área de texto.

[HttpPost] 
public ActionResult Index(string code) 
{ 
    var reportWriter = new StringWriter(); 
    var settings = new CompilerSettings(); 
    var printer = new ConsoleReportPrinter(reportWriter); 
    var reports = new Report(printer); 
    var eval = new Evaluator(settings, reports); 

    var model = new CodeViewModel(); 
    model.Code = code; 
    eval.Run(code); 
    model.Result = reportWriter.ToString(); 

    return View("Index", model); 
} 

Ahora supongamos que el código es una cadena como esta:

using System; 
public class MyClass 
{ 
    public void DoSomething() 
    { 
     Console.WriteLine("hello from DoSomething!"); 
    } 
} 

¿Cómo Bootstrap esto (es decir, una instancia de un objeto MyClass y llamar DoSomething en él)? He intentado simplemente añadiendo new MyClass().DoSomething(); hasta el final, pero me sale esto:

{interactive}(1,2): warning CS0105: The using directive for `System' appeared previously in this namespace 
{interactive}(1,8): (Location of the symbol related to previous warning) 
{interactive}(11,1): error CS1530: Keyword `new' is not allowed on namespace elements 
{interactive}(11,4): error CS1525: Unexpected symbol `MyClass', expecting `class', `delegate', `enum', `interface', `partial', or `struct' 

¿Qué me falta?

+1

¿Podría publicar el archivo completo que contiene la clase MyClass? –

+0

El código de MyClass no está en un archivo, está en una cadena. –

Respuesta

5
var reportWriter = new StringWriter(); 
var settings = new CompilerSettings(); 
var printer = new ConsoleReportPrinter(reportWriter); 
var reports = new Report(printer); 
var eval = new Evaluator(settings, reports); 

eval.Run(code); 

eval.Run(@" 
    var output = new System.IO.StringWriter(); 
    Console.SetOut(output); 
    new MyClass().DoSomething();"); 

var model = new CodeViewModel(); 
model.Code = code; 

if (reports.Errors > 0) 
    model.Result = reportWriter.ToString(); 
else 
    model.Result = (string) eval.Evaluate("output.ToString();"); 

return View("Index", model); 
1

Aunque esta pregunta ya se ha aceptado, estaba teniendo un problema similar cuando me encontré con esta publicación. Finalmente lo descubrí, así que pensé en publicar aquí en caso de que alguien más tenga problemas.

No puede mezclar using y otras declaraciones en la misma llamada al Evaluator. De the documentation en el Mono.CSharp REPL:

Los que utilizan declaración debe aparecer por sí mismos y no se pueden mezclar con las declaraciones regulares en una sola línea.

Dado que este es el uso de las llamadas individuales a la Evaluator para cada línea, esta misma restricción se aplica para invocar la Evaluator desde la aplicación.