2011-05-18 130 views
5

我已经广泛使用Python来做各种adhoc数据管理和辅助任务。自从我学习C#以来,我认为看看我是否可以用C#重写这些脚本中的某些脚本会很有趣。使用C#编写脚本?

是否有一个可执行文件需要.cs文件并运行它ala python?

+1

检查在这里运行名为server.csx一个C#脚本文件 - http://stackoverflow.com/questions/1660452/c-interpreter-without-compilation – Cynede 2011-05-18 07:39:51

+0

Visual Studio中有一个[立即窗口](http://msdn.microsoft.com/en-us/library/f177hahy(v = VS.100).aspx)你可以玩 – bitxwise 2011-05-18 07:41:53

+1

虽然不完全相同的事情,[LINQPad](http: //www.linqpad.net/)可以像Python的REPL一样工作。 – 2011-05-18 07:41:55

回答

4

你可以做这样的事情(创建类似这样的代码,一个控制台应用程序)

... 
using System.Reflection; 
using System.CodeDom.Compiler; 
... 

namespace YourNameSpace 
{ 
    public interface IRunner 
    { 
    void Run(); 
    } 

    public class Program 
    { 
    static Main(string[] args) 
    { 
     if(args.Length == 1) 
     { 
     Assembly compiledScript = CompileCode(args[0]); 
     if(compiledScript != null) 
      RunScript(compiledScript); 
     } 
    } 

    private Assembly CompileCode(string code) 
    { 
     Microsoft.CSharp.CSharpCodeProvider csProvider = new 
Microsoft.CSharp.CSharpCodeProvider(); 

     CompilerParameters options = new CompilerParameters(); 
     options.GenerateExecutable = false; 
     options.GenerateInMemory = true; 

     // Add the namespaces needed for your code 
     options.ReferencedAssemblies.Add("System"); 
     options.ReferencedAssemblies.Add("System.IO"); 
     options.ReferencedAssemblies.Add(Assembly.GetExecutingAssembly().Location); 

     // Compile the code 
     CompilerResults result; 
     result = csProvider.CompileAssemblyFromSource(options, code); 

     if (result.Errors.HasErrors) 
     { 
     // TODO: Output the errors 
     return null; 
     } 

     if (result.Errors.HasWarnings) 
     { 
     // TODO: output warnings 
     } 

     return result.CompiledAssembly; 
    } 

    private void RunScript(Assembly script) 
    { 
     foreach (Type type in script.GetExportedTypes()) 
     { 
     foreach (Type iface in type.GetInterfaces()) 
     { 
      if (iface == typeof(YourNameSpace.Runner)) 
      { 
      ConstructorInfo constructor = type.GetConstructor(System.Type.EmptyTypes); 
       if (constructor != null && constructor.IsPublic) 
       { 
       YourNameSpace.IRunner scriptObject = constructor.Invoke(null) as 
YourNameSpace.IRunner; 

       if (scriptObject != null) 
       { 
        scriptObject.Run(); 
       } 
       else 
       { 
        // TODO: Unable to create the object 
       } 
       } 
       else 
       { 
       // TODO: Not implementing IRunner 
       } 
      } 
      } 
     } 
     } 
    } 
} 

创建这个控制台应用程序后,您可以在命令提示符下这样开始的:

YourPath:\> YourAppName.exe "public class Test : IRunnder { public void Run() { 
Console.WriteLine("woot"); } }" 

你可以很容易地改变Main方法接受文件,而不是内嵌代码,所以你的控制台应用程序将有一个呈三角行为的Python或Ruby解释器。只需将文件名传递给应用程序,然后在主函数中使用StreamReader读取它,并将内容传递给CompileCode方法。事情是这样的:

static void Main(string[] args) 
{ 
    if(args.Length == 1 && File.Exists(args[0])) 
    { 
    var assambly = CompileCode(File.ReadAllText(args[0])); 
    ... 
    } 
} 

和命令行:

YourPath:\> YourApp.exe c:\script.cs 

您必须实现IRunner界面,你可以也只需拨打一个硬编码的启动方法不继承接口,即只是为了展示编译类的概念并执行它。

希望它有帮助。

0

将C#作为脚本运行的最新和最佳方式是利用Roslyn。这是用C#编写的C#编译器。

Glenn Block,Justin Rusbatch和Filip Wojcieszyn已将Roslyn打包成一个名为scriptcs的程序,该程序完全符合您的需求。

你可以在这里找到项目。 http://scriptcs.net/

你可以通过调用

scriptcs server.csx