挖新闻 > 软件 > 一个简单的C#在线IDE示例

一个简单的C#在线IDE示例

来源:新浪科技 作者:Freedom 时间:2008-06-14 17:00:02

【IT168技术文档】

做一个简单的C#在线IDE主要解决两个问题:
一是如何将网页上文本框的代码编译并执行;
二是如何将程序运行结果在网页上输出.

第一个问题不难, dotNET已经有现成的C#编译类CSharpCodeProvider(或是其它语言的),再使用CompilerParameters类做为编译参数,就可以很容易的实现.

第二个问题, 举最简单情况, 就是将Console.Write方法输出的内容在网页上显示出来.这其实也很好办,只要在编译之前, 在输出语句做一个替换, 将输出的内容存到另一个地方.等运行结束后, 再从那个地方取出来就是了.

代码实现如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
  
namespace VSOnline.Framework
{
   ///
   /// 自定义的输出类
   ///  
   public class Consoler
   {
       //存储所有输出 
       public static Dictionary Outputs { get; set; }
  
       static Consoler()
       {
             Outputs = new Dictionary();
       }
  
       #region 输出操作 
  
       //当前输出 
       public List Output { get; private set; }
  
       public Consoler()
        {
           Output = new List();
      }
  
       public void Write(object str)
        {
           Output.Add(str.ToString());
        }
  
        public void WriteLine(object str)
      {
         Output.Add(str.ToString() + "n");
        }
      #endregion 
   }
}
using System;
using System.Reflection;
using Microsoft.CSharp;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.Linq;
using System.Web;
  
namespace VSOnline.Framework
{
   ///
   /// 代码执行类
   ///  
  public class CodeRun
  {
        ///
       /// Framework版本,可选择v2.0, v3.0, v3.5
       ///  
       private string CompilerVersion { get; set; }
  
       ///
       /// 构造函数
       ///
       /// Framework版本,可选择v2.0, v3.0, v3.5 
 
  public CodeRun(string compilerVersion)
   {
       CompilerVersion = compilerVersion;
   }
  
   ///
   /// 构造函数,默认为3.5版本
   ///  
   public CodeRun()
   {
       CompilerVersion = "v3.5";
   }
  
   ///
   /// 动态编译并执行代码
   ///
   /// 代码
   /// 返回输出内容 
   public List Run(string code, string id, params string[] assemblies)
   {
       Consoler.Outputs.Add(id, new Consoler());
       CompilerParameters compilerParams = new CompilerParameters();
       //编译器选项设置 
       compilerParams.CompilerOptions = "/target:library /optimize";
       //compilerParams.CompilerOptions += @" /lib:""C:Program FilesReference AssembliesMicrosoftFrameworkv3.5""";
       //编译时在内存输出 
      compilerParams.GenerateInMemory = true;
         //生成调试信息 
         compilerParams.IncludeDebugInformation = false;
       //添加相关的引用 
       foreach (string assembly in assemblies)
       {
           compilerParams.ReferencedAssemblies.Add(assembly);
       }
       compilerParams.ReferencedAssemblies.Add("mscorlib.dll");
       compilerParams.ReferencedAssemblies.Add("System.dll");
       if (this.CompilerVersion == "v3.5")
       {
           compilerParams.ReferencedAssemblies.Add("System.Core.dll");
       }
  
       string path = "";
       try
       {
           path = HttpContext.Current.Server.MapPath("/bin/");
       }
         catch { }
  
       compilerParams.ReferencedAssemblies.Add(path + "VSOnline.Framework.dll");
  CSharpCodeProvider compiler = new CSharpCodeProvider(new Dictionary() { { "CompilerVersion", CompilerVersion } });
       //编译 
       code = code.Replace("Console.WriteLine", string.Format("VSOnline.Framework.Consoler.Outputs["{0}"].WriteLine", id));
       code = code.Replace("Console.Write", string.Format("VSOnline.Framework.Consoler.Outputs["{0}"].Write", id));
       CompilerResults results = compiler.CompileAssemblyFromSource(compilerParams, code);
         //错误 
       if (results.Errors.HasErrors)
       {
             foreach (CompilerError error in results.Errors)
             {
                  Consoler.Outputs[id].Output.Add(error.ErrorText + "n");
             }
             return ReturnOutput(id);
        }
         //创建程序集 
       Assembly asm = results.CompiledAssembly;
         //获取编译后的类型 
         object mainClass = asm.CreateInstance("Program");
       Type mainClassType = mainClass.GetType();
       //输出结果 
       mainClassType.GetMethod("Main").Invoke(mainClass, null);
  
       return ReturnOutput(id);
   }
  
   private List ReturnOutput(string id)
   {
         string[] output = new string[Consoler.Outputs[id].Output.Count];
         Consoler.Outputs[id].Output.CopyTo(output, 0);
         Consoler.Outputs.Remove(id);
  
         return output.ToList();
   }
 }
}
测试代码:
using VSOnline.Framework;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Collections.Generic;
using System;
using FastDev.Core;
using System.Linq;
  
namespace Test
{
   [TestClass()]
   public class CodeRunTest
   {
       [TestMethod()]
       public void RunTest()
       {
           CodeRun target = new CodeRun();
  
//注意:以下是一个多行的 string 
           string code = @"
                          using System;
  
                          public class Program
                          {
                               public static void Main()
                              {
                                   for(int index = 1;index <= 3;index++)
                                   {
                                          Console.Write(index);
                                   }
                               }
                           }  ";   // 多行 string结束

           List expected = new List() { "1", "2", "3" };
           List actual;
     actual = target.Run(code, "1");
           Assert.AreEqual(true, expected.SerializeEqual(actual));
  
           actual = target.Run(code, "2");
           Assert.AreEqual(true, expected.SerializeEqual(actual));
       }
  
       [TestMethod()]
       public void Run35Test()
       {
           CodeRun target = new CodeRun();
  
           string code = @"
                  using System;
                  using System.Collections;
                  using System.Collections.Generic;
                  using System.Linq;
  
                  public class Program
                  {
                       public static string Name { get; set; }
  
                        public static void Main()
                        {
                            Name = ""3"";
                            Console.Write(Name);
                        }
                  } ";
             List actual;
             actual = target.Run(code, "1", "System.Core.dll");
             Assert.AreEqual("3", actual[0]);
        }
   }
}
标签: IDE 示例 在线 C# 简单 一个
[收藏] [推荐] [评论] [打印] [关闭] 点击:
评论:一个简单的C#在线IDE示例
发表评论:【一个简单的C#在线IDE示例】,不超过250字,请自觉遵守互联网相关政策法规。

匿名评论? 验证码: