Exeファイルやその他のファイルを生成せずに、保存されたコードをコンパイルして実行できるかどうか疑問に思っていました。基本的には、メモリからファイルを実行します。
基本的に、メインアプリケーションにはいくつかのコード(変更される可能性のあるコード)が格納されており、コードをコンパイルして実行する必要があります。ファイルを作成せずに。
ファイルを作成し、プログラムを実行してから、ファイルを削除することはできません。コンパイルされたコードはメモリから実行する必要があります。
コード例、ポインタ、またはほとんど何でも大歓迎です:)
using (Microsoft.CSharp.CSharpCodeProvider foo =
new Microsoft.CSharp.CSharpCodeProvider())
{
var res = foo.CompileAssemblyFromSource(
new System.CodeDom.Compiler.CompilerParameters()
{
GenerateInMemory = true
},
"public class FooClass { public string Execute() { return \"output!\";}}"
);
var type = res.CompiledAssembly.GetType("FooClass");
var obj = Activator.CreateInstance(type);
var output = type.GetMethod("Execute").Invoke(obj, new object[] { });
}
これにより、含まれているソースコード文字列から単純なクラスがコンパイルされ、クラスがインスタンス化されて、そのクラスで関数が反射的に呼び出されます。
System.Linq.Expressions
を使用してTimの回答に追加する方法の例を次に示します。明らかにそれは最も美しいコードではありませんが、この素敵なツリーのような形でそれを持っていると、開発がとても簡単になります。
private Expression<IsWordChar> CreateIsWordCharExpression()
{
var e = Expression.Parameter(typeof(int), "e");
var c = Expression.Variable(typeof(char), "c");
var returnLabel = Expression.Label(Expression.Label(typeof(bool)), _falseConstant);
var lambda = Expression.Lambda<IsWordChar>(
Expression.Block(
new[] { c },
Expression.IfThen(
Expression.OrElse(
Expression.Equal(e, Expression.Constant(-1)),
Expression.Equal(e, _inputLengthVar)
),
Expression.Return(returnLabel.Target, _falseConstant)
),
Expression.Assign(c, Expression.MakeIndex(_str, _stringCharsPropertyInfo, new[] { e })),
Expression.IfThenElse(
Expression.OrElse(
Expression.OrElse(
Expression.OrElse(
Expression.AndAlso(
Expression.GreaterThanOrEqual(c, Expression.Constant('a')),
Expression.LessThanOrEqual(c, Expression.Constant('z'))
),
Expression.AndAlso(
Expression.GreaterThanOrEqual(c, Expression.Constant('A')),
Expression.LessThanOrEqual(c, Expression.Constant('Z'))
)
),
Expression.AndAlso(
Expression.GreaterThanOrEqual(c, Expression.Constant('0')),
Expression.LessThanOrEqual(c, Expression.Constant('1'))
)
),
Expression.Equal(c, Expression.Constant('_'))
),
Expression.Return(returnLabel.Target, _trueConstant),
Expression.Return(returnLabel.Target, _falseConstant)
),
returnLabel
),
"IsWordChar",
new[] { e }
);
return lambda;
}
それが可能だ。書きたいコードの量と種類に応じて、簡単または難しいです。
System.Linq.Expressions
(簡単ですが制限されています)System.Reflection.Emit
(デバッグは難しいが、不可能ではない)編集:。NET 4.0より前では、System.Linq.Expressions
は、C#の1行に収まるものに制限されます。つまり、if、while、変数の割り当てなどはありません。
はい、できます。とても遅いですが、確かにできます。 CodeDOMまたは.Netの(new CSharpCodeProvider().CreateCompiler())
を見てください。
System.CodeDom
を調べてください。それはあなたが探していることを正確に行います。
Monoでは、CSharp.Evaluatorを使用します。これは、メモリ内で真に機能します。v。ボンネットの下でファイルに書き込み、読み取りを行う、前述の他のソリューションのいくつか。