Скомпилировать и выполнить динамический код, не генерируя EXE?

22
задан caesay 6 July 2010 в 17:57
поделиться

8 ответов

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[] { });
}

Это компилирует простой класс из включенной строки исходного кода, затем создает экземпляр класса и рефлексивно вызывает на нем функцию.

36
ответ дан 29 November 2019 в 04:33
поделиться

Да, вы можете сделать это. Это очень медленно, но вы, безусловно, можете это сделать. Посмотрите на CodeDOM или (new CSharpCodeProvider().CreateCompiler()) в .Net.

1
ответ дан Brian Genisio 29 November 2019 в 04:33
поделиться

В Mono вы используете CSharp.Evaluator. Он действительно работает в памяти v. Некоторые другие упомянутые решения, которые записывают и читают в файле под капотом.

0
ответ дан user430788 29 November 2019 в 04:33
поделиться

Сложно, если вообще невозможно, скомпилировать и выполнить C # без создания файла, потому что ... Ну, вот что такое компиляция - превращение языка в исполняемый файл. То, что вы ищете, это какая-то функциональность сценариев. То, что вы описали в своем вопросе, по сути, является различием между интерпретируемым языком и скомпилированным языком. См. Википедия: язык сценариев .

В зависимости от того, для чего вы будете использовать эту функцию, вы можете широко использовать язык сценариев, такой как Python, Ruby или Lua , Вот пример: Как запустить скрипт Python из C #?

Это сделает вашу прикладную программу зависимой от python.exe (или любого исполняемого файла, который вам понадобится для запуска языка сценариев, который вы выбирать). Если вы хотите избежать этого, может быть не сложно создать свой собственный язык сценариев, для которого ваше приложение выполняет среду выполнения, в зависимости от того, что вам нужно делать с внедренным сценарием.

Редактировать: Первый абзац - мусор. Сожалею. См. http://msdn.microsoft.com/en-us/library/8ffc3x75%28v=vs.110%29.aspx

.
-2
ответ дан Community 29 November 2019 в 04:33
поделиться

Вот пример того, как использовать 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;
}
5
ответ дан 29 November 2019 в 04:33
поделиться

Это возможно. Это легко или сложно, в зависимости от того, сколько и какой код вы хотите написать.

  • Компилировать однострочные выражения: System.Linq.Expressions (просто, но ограниченно)
  • Компилировать целые программы: System.Reflection.Emit (трудно отлаживать, но не невозможно)

Изменить: Обратите внимание, что до .NET 4.0 System.Linq.Expressions ограничивалось тем, что вы могли уместить в одной строке C #: то есть, нет, если, while, присвоение переменных и т. д.

4
ответ дан 29 November 2019 в 04:33
поделиться

Посмотрите на System.CodeDom. Он сделает именно то, что вы ищете.

1
ответ дан 29 November 2019 в 04:33
поделиться

Также взгляните на встраивание языка сценариев, такого как Python, Ruby, Lua и т. Д. все они поддерживают выполнение кода из памяти без записи на диск.

-1
ответ дан 29 November 2019 в 04:33
поделиться