C # и динамические строковые скрипты - PullRequest
2 голосов
/ 17 мая 2011

Мне бы хотелось получить несколько идей о том, как мне реализовать ключевую часть проекта, над которым я работаю.По сути это отображение данных, где я копирую поле x и помещаю его в поле y.Однако должна существовать некоторая способность динамически изменять (с помощью манипуляции со строками) это значение во время перехода.

То, что я хотел бы, - это текстовое поле, в котором пользователь может вводить сценарий, позволяющий им изменять это значение с помощью сценариев.язык, в идеале VBScript.Это тогда позволило бы им делать простые манипуляции, такие как этот пример, который взял бы подстроку:

Mid({input_value}, 2, 4)

Где

{input_value} 

Будет заменено фактическим значением во время выполнения.

Так, например, если входные данные из "поля x" были "Это тест" и они использовали приведенный выше пример start = 2 и length = 4, значение, сохраненное в "поле y", будет равно "его "

Я знаю, как я мог запустить VBScript из C # как scipt, это не проблема.Однако возможно ли выполнить и оценить srcipts, как указано выше, во время выполнения и записать вывод обратно в переменную C #?

В противном случае, есть ли у кого-нибудь какие-либо предложения о том, как я мог бы подойти к этому?* Большое спасибо

Ответы [ 2 ]

1 голос
/ 17 мая 2011

Возможно, вы захотите взглянуть на язык DLR , такой как IronPython или IronRuby.Оба позволяют встраивать, и у Майкла Фурда есть учебник о том, как встраивать их в приложение.

Если вы используете стандартные интерфейсы DLR, я считаю, что вы можете встраивать любой язык, включая DLRBasic и ASP Classic Compiler .У Бен Холла есть статья о встраивании IronRuby в производственное приложение для Red Gate.

Я думаю, что вам нужно рассмотреть методы SetVariable () и GetVariable (), показанные ниже, для примера установкии вернуть данные из сценариев:

public string evaluate(string x, string code)
{
    scope.SetVariable("x", x);
    scope.SetVariable("button", this.button);

    try
    {
        ScriptSource source = engine.CreateScriptSourceFromString(code,
            SourceCodeKind.Statements);

        source.Execute(scope);
    }
    catch (Exception ex)
    {
        return "Error executing code: " + ex.ToString();
    }

    if (!scope.VariableExists("x"))
    {
        return "x was deleted";
    }
    string result = scope.GetVariable<object>("x").ToString();
    return result;
}

Этот пример взят из http://www.voidspace.org.uk/ironpython/dlr_hosting.shtml.

0 голосов
/ 17 мая 2011

Вот рабочий пример использования компиляции выражений во время выполнения. Я заимствовал концепцию и большую часть кода отсюда .

static void Main(string[] args)
{
    string input = "This is a test";
    string method = "Mid(x, 2, 4)";  // 'x' represents the input value
    string output = Convert(method, input);
    Console.WriteLine("Result: " + output);
    Console.ReadLine();
}

// Convert input using given vbscript logic and return as output string
static string Convert(string vbscript, string input)
{
    var func = GetFunction(vbscript);
    return func(input);
}

// Create a function from a string of vbscript that can be applied
static Func<string, string> GetFunction(string vbscript)
{
    // generate simple code snippet to evaluate expression
    VBCodeProvider prov = new VBCodeProvider();
    CompilerResults results = prov.CompileAssemblyFromSource(
        new CompilerParameters(new[] { "System.Core.dll" }),
        @"
Imports System
Imports System.Linq.Expressions
Imports Microsoft.VisualBasic

Class MyConverter

Public Shared Function Convert() As Expression(Of Func(Of String, String))
    return Function(x) " + vbscript + @"
End Function

End Class
"
        );

    // make sure no errors occurred in the conversion process
    if (results.Errors.Count == 0)
    {
        // retrieve the newly prepared function by executing the code
        var expr = (Expression<Func<string, string>>)
            results.CompiledAssembly.GetType("MyConverter")
                .GetMethod("Convert").Invoke(null, null);
        Func<string, string> func = expr.Compile();

        // create a compiled function ready to apply and return
        return func;
    }
    else
    {
        return null;
    }
}
...