使用IronRuby或IronPython修改C#对象列表

时间:2010-08-09 02:24:55

标签: c# .net export ironpython ironruby

如果我有一个对象列表,例如。 List<Foo>其中Foo有几个属性,然后我可以为每一行创建一个或多个ironruby或ironpython脚本。

这是一些伪代码:

var items = new List<Foo>();
foreach(var item in items) {
   var pythonfunc = getPythonFunc("edititem.py");
   item = pythonfunc(item);
}

我需要一种动态方法来修改代码存储在数据库或文件中的列表。

如果您认为有更好的方法可以执行此操作,或者有其他选择,以便可以为可以从数据库中提取客户端特定数据的客户端(导出)编写自定义例程,请发表评论或留下建议。

由于

1 个答案:

答案 0 :(得分:4)

之前我使用过这种方法,都将IronPython脚本保存在数据库和文件中。我喜欢的模式是存储具有惯例已知名称的Python函数。换句话说,如果您正在处理类型为Foo的对象,则可能在.py文件或表中有一个名为“foo_filter”的Python函数。最终,您可以执行Python文件并将函数解析为函数引用的字典。

快速示例应用...

你的foo课程:

public class Foo {
    public string Bar { get; set; }
}

设置Foo并调用getPythonFunc(i);

var items = new List<Foo>() {
    new Foo() { Bar = "connecticut" },
    new Foo() { Bar = "new york" },
    new Foo() { Bar = "new jersey" }                    
};

items.ForEach((i) => { getPythonFunc(i); Console.WriteLine(i.Bar); });

快速而肮脏的getPythonFun实现......显然应该缓存ScriptXXX对象图,GetVariable()检索的变量也应如此缓存。

static void getPythonFunc(Foo foo) {

    ScriptRuntimeSetup setup = ScriptRuntimeSetup.ReadConfiguration();
    ScriptRuntime runtime = new ScriptRuntime(setup);
    runtime.LoadAssembly(Assembly.GetExecutingAssembly());
    ScriptEngine engine = runtime.GetEngine("IronPython");
    ScriptScope scope = engine.CreateScope();

    engine.ExecuteFile("filter.py", scope);

    var filterFunc = scope.GetVariable("filter_item");
    scope.Engine.Operations.Invoke(filterFunc, foo);
}

filter.py的内容:

def filter_item(item):
    item.Bar = item.Bar.title()

基于属性应用规则的简单方法(不是在Foo上添加Size属性):

var items = new List<Foo>() {
    new Foo() { Bar = "connecticut", Size = "Small" },
    new Foo() { Bar = "new york", Size = "Large" },
    new Foo() { Bar = "new jersey", Size = "Medium" }
};

更改getPythonFun()中调用ScriptScope的GetVariable()的行:

var filterFunc = scope.GetVariable("filter_" + foo.Size.ToLower());

filter.py的新内容

def filter_small(item):
    item.Bar = item.Bar.lower()

def filter_medium(item):
    item.Bar = item.Bar.title()

def filter_large(item):
    item.Bar = item.Bar.upper()

我在http://www.codevoyeur.com/Articles/Tags/ironpython.aspx处有一堆更完整的样本。