2012-09-28 4 views
6

Sto provando a scrivere un'app di insegnamento C# interattiva, in cui l'utente può sperimentare/modificare esempi di codice e vedere cosa succede (un po 'come jsfiddle).Esecuzione di un mini-programma in Mono.Csharp

Ho trovato molti esempi per piccole espressioni o usi REPL-like di Mono.Csharp come compilatore di runtime, ma non riesco a trovare un esempio in cui viene eseguito un "mini programma".

Ecco il mio codice giocattolo finora (un'azione MVC). Il parametro "codice" viene pubblicato direttamente da una textarea.

[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); 
} 

Ora supponiamo che il codice è una stringa come questa:

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

Come faccio Bootstrap questo (cioè istanziare un oggetto MyClass e chiamare DoSomething su di esso)? Ho provato solo aggiungendo new MyClass().DoSomething(); fino alla fine, ma ottengo questo:

{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' 

Che cosa mi manca?

+1

Potresti postare l'intero file che contiene la classe MyClass? –

+0

Il codice MyClass non è in un file, è in una stringa. –

risposta

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

Anche se questa domanda è già stata accettata, ho riscontrato un problema simile quando ho trovato questo post. Alla fine ho capito, quindi ho pensato di postare qui nel caso in cui qualcun altro si mette nei guai.

Non è possibile combinare using e altre istruzioni nella stessa chiamata allo Evaluator. Dal the documentation sul Mono.CSharp REPL:

Gli utilizzando dichiarazioni devono apparire da soli e non possono essere miscelati con le dichiarazioni periodiche in una sola riga.

Poiché si tratta di utilizzare le singole chiamate al Evaluator per ogni linea, questa stessa restrizione vale per invocare la Evaluator dall'applicazione.