【问题标题】:c# and dynamic string scriptingc# 和动态字符串脚本
【发布时间】:2011-05-17 01:56:36
【问题描述】:

我很想知道我应该如何实施我正在从事的项目的关键部分。本质上它是数据映射,我复制字段 x 并将其放入字段 y。但是,需要有某种能力在转换期间动态更改(使用字符串操作)该值。

我想要的是一个文本框,用户可以在其中输入脚本,允许他们使用脚本语言修改该值,最好是 VBScript。这将允许他们进行简单的操作,例如这个例子,这将需要一个子字符串:

Mid({input_value}, 2, 4)

在哪里

{input_value} 

将在运行时替换为实际值。

因此,例如,如果“字段 x”的输入是“这是一个测试”,并且他们使用上面的 start = 2 和长度 = 4 的示例,则保存到“字段 y”中的值将是“his "

我知道如何将 C# 中的 VBScript 作为 scipt 运行,这不是问题。但是,是否可以在运行时运行和评估上述脚本并将输出记录回 C# 变量中?

否则,有人对我如何处理这个问题有任何建议吗?

非常感谢

【问题讨论】:

    标签: c# scripting dynamic


    【解决方案1】:

    您可能想查看基于DLR 的语言,例如 IronPython 或 IronRuby。两者都允许嵌入,Michael Foord 有一个 tutorial 说明如何将这些嵌入到应用程序中。

    如果您使用标准 DLR 接口,我相信您可以嵌入任何语言,包括 DLRBasicASP Classic Compiler。 Ben Hall 在 Red Gate 的生产应用程序中有一篇关于 IronRuby embedding 的文章。

    我认为您需要查看下面显示的 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

    【讨论】:

    • 感谢您的帖子,我现在正在查看这些选项。
    • 但是我有一个问题 - 可以动态运行脚本,但是否可以将 IronRuby/IronPython 返回的结果返回到 C# 变量中?
    • 应该是。我认为您应该研究 .NET 4.0 上的 C# 'dynamic' 关键字。在早期版本的 .NET 上应该有解决方案,但我需要查找。
    • 感谢您的回复,我会将问题标记为已回答
    【解决方案2】:

    这是一个使用表达式运行时编译的工作示例。我借用了概念和大部分代码from here

    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;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-15
      • 2017-08-27
      • 2017-02-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多