2011-02-03 23 views
2

短い質問、 .NET 4.0では、メソッド本体を表す文字列をFunc/Actionにコンパイルする方法がありますか、そうするライブラリがありますか?から文字列へ

明確化:

私は任意のDLLを生成しない何かを必要とする、それが、JavaScriptでのeval()のようなもの、完全に動的にする必要があります。私はdllを作成せずに文字列をFunc/Actionに変換する必要があります。

+0

あなたはJavaScriptがeval()で何かをしていることを意味していますか? –

+2

ランタイムまたはデザインタイムソリューションをお探しですか?後者の場合、MyGenerationやT4などのコード生成テンプレートをいつでも使用できますか?前者の場合は、Microsoft.CSharpとSystem.CodeCom.Compilerの名前空間を調べましたか? – bitxwise

答えて

4

CSharpCodeProvider classを使用すると、ソースコードをアセンブリにコンパイルできます。例えば

var compiler = new CSharpCodeProvider(new Dictionary<string, string> { { "CompilerVersion", "v4.0" } }); 
var options = new CompilerParameters { OutputAssembly = path); 
var results = compiler.CompileAssemblyFromFile(options, sourceFile); 

単一の関数をコンパイルするには、リフレクションを使用してデリゲートを取得し、その後、完全なソースファイルを作成するために、適切なusing文とクラスでラップすることができます

var assembly = results.CompiledAssembly; 
var method = assembly.GetType("WrapperClassName").GetMethod("MethodName"); 
var delegate = (Action)Delegate.CreateDelegate(typeof(Action), method); 
more complete exampleの場合

static readonly Assembly[] References = new[] { typeof(Enumerable).Assembly, typeof(Component).Assembly }; 
public Action CompileMethodstring source) { 
    var options = new CompilerParameters(References.Select(a => a.Location).ToArray()) { 
     GenerateInMemory = true 
    }; 
    string fullSource = @"public static class HolderClass { public static void Execute() { \r\n" + source + "\r\n} }"; 
    try { 
     var compiler = new CSharpCodeProvider(new Dictionary<string, string> { { "CompilerVersion", "v4.0" } }); 

     var results = compiler.CompileAssemblyFromSource(options, fullSource); 

     if (results.Errors.Count > 0) 
      throw new InvalidOperationException(String.Join(
       Environment.NewLine, 
       results.Errors.Cast<CompilerError>().Select(ce => ce.ErrorText) 
      )); 

     return (Action)Delegate.CreateDelegate(
      typeof(Action), 
      results.CompiledAssembly.GetType("HolderClass").GetMethod("Execute") 
     ); 
    } finally { options.TempFiles.Delete(); } 
} 
+0

実際には、これはうまくいくかもしれませんが、ちょっとしたコード生成が必要です。 – epitka

0

CSharpCodeProviderがあなたが探しているものかもしれません。ただし、有効なC#コードを作成する必要があります(つまり、そのメソッドのクラスを作成する必要があります)。

1

また、それはまた、あなたが次の操作を行うために埋め込まれたスクリプトプラットフォームであるCS-Script.Netを使用することができます。

dynamic script = CSScript.LoadCode(@"using System; 
            public class Script 
            { 
             public void SayHello(string greeting) 
             { 
              Console.WriteLine(greeting); 
             } 
            }") 
            .CreateObject("*"); 
script.SayHello("Hello World!"); 

は、私は今、ほぼ2年間の生産に使用してきたが、それは素晴らしい方法になっています構成可能なアプリケーションを作成します。興味があれば私にはsample projectがあります。

+0

これは非常に有望です。それが中程度の信頼で動作するかどうか知っていますか? – epitka

+0

私が知る限り、はい。サポートされているスクリプトモデルへのリンクは次のとおりです。http://csscript.net/help/Type_sharing_patern.htmlプロジェクトオーナーは非常に反応があり、いつでも追加の質問で彼に連絡することができます。 –