2011-05-18 139 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