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[] { });
}
Это компилирует простой класс из включенной строки исходного кода, затем создает экземпляр класса и рефлексивно вызывает на нем функцию.
Да, вы можете сделать это. Это очень медленно, но вы, безусловно, можете это сделать. Посмотрите на CodeDOM или (new CSharpCodeProvider().CreateCompiler())
в .Net.
В Mono вы используете CSharp.Evaluator. Он действительно работает в памяти v. Некоторые другие упомянутые решения, которые записывают и читают в файле под капотом.
Сложно, если вообще невозможно, скомпилировать и выполнить C # без создания файла, потому что ... Ну, вот что такое компиляция - превращение языка в исполняемый файл. То, что вы ищете, это какая-то функциональность сценариев. То, что вы описали в своем вопросе, по сути, является различием между интерпретируемым языком и скомпилированным языком. См. Википедия: язык сценариев . Strike>
В зависимости от того, для чего вы будете использовать эту функцию, вы можете широко использовать язык сценариев, такой как Python, Ruby или Lua , Вот пример: Как запустить скрипт Python из C #?
Это сделает вашу прикладную программу зависимой от python.exe (или любого исполняемого файла, который вам понадобится для запуска языка сценариев, который вы выбирать). Если вы хотите избежать этого, может быть не сложно создать свой собственный язык сценариев, для которого ваше приложение выполняет среду выполнения, в зависимости от того, что вам нужно делать с внедренным сценарием.
Редактировать: Первый абзац - мусор. Сожалею. См. http://msdn.microsoft.com/en-us/library/8ffc3x75%28v=vs.110%29.aspx
. Вот пример того, как использовать System.Linq.Expressions
для добавления к ответу Тима. Очевидно, что это не самый красивый код, но наличие его в этой красивой древовидной форме упрощает разработку.
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 #: то есть, нет, если, while, присвоение переменных и т. д.
Посмотрите на System.CodeDom
. Он сделает именно то, что вы ищете.
Также взгляните на встраивание языка сценариев, такого как Python, Ruby, Lua и т. Д. все они поддерживают выполнение кода из памяти без записи на диск.