IronPython分析Lambda表达式

作者:网络 来源:佚名 更新时间:2008-10-16 23:29:56 点击:

在我们的.net项目中,要使用到自定义公式功能,我们利用了ironpython的lambda功能,可以方便的计算值,但是我们发现,如果表达式涉及的属性发生改变时,公式必须重新计算,怎样析表达式知道到底访问了哪些属性呢?

在我们的.net项目中,要使用到自定义公式功能,我们利用了ironpython的lambda功能,可以方便的计算值,但是我们发现,如果表达式涉及的属性发生改变时,公式必须重新计算,怎样析表达式知道到底访问了哪些属性呢?

仔细研究发现ironpython提供了这样的功能:

以下为引用的内容:

systemstate state = new systemstate();
   compilercontext context = new compilercontext();
  
   parser p = parser.fromstring(state, context, "activeobject.contact.address + 'ds'");
   ironpython.compiler.ast.expression ex = p.parsetestlistasexpression();

上面的代码分析了表达式:activeobject.contact.address + 'ds', 这里用了parser类可以分析出表达式,使用vs对象查看器,可以理解结果:

问题还没有完全解决,我想结果有了,我总不能自己递归所有结构吧?哇,怎么也有20多种类型,在看看,嗯,还有这个:

以下为引用的内容:

  class program {
   static void main(string[] args) {
   systemstate state = new systemstate();
   compilercontext context = new compilercontext();
  
   parser p = parser.fromstring(state, context, "activeobject.contact.address + 'ds'");
   ironpython.compiler.ast.expression ex = p.parsetestlistasexpression();
  
   mywalker w = new mywalker();
   ex.walk(w);
   }
   }
  
   class mywalker : astwalker {
   public override bool walk(fieldexpression node) {
   console.writeline("walk:{0},{1}", node.name, node.target);
   return base.walk(node);
   }
   }

cool!!我重载的虚方法被调用了两次,告诉我有2次字段的访问。

在.net 3.5中提供了lambda的结构描述类,但我是没有找到动态编译分析的类。看博客园的朋友说:本来有个dynamicexpression的类提供了动态编译功能,但是现在的.net 3.5砍掉了,但是在linq 101 samples中却有源代码,靠。

注意:本程序使用ironpython 的1.0版本,2.0版本的方法已经不同。 下面是2.0的代码:

以下为引用的内容:

class program {
   static void main(string[] args) {
   //引擎
   ironpython.hosting.pythonengine engine = ironpython.hosting.pythonengine.currentengine;
   //代码单元
   sourcecodeunit unit = new sourcecodeunit(engine, "activeobject.contact.address + 'ds'");
   //上下文和选项
   compilercontext context = new compilercontext(unit);
   ironpython.pythonengineoptions option = new ironpython.pythonengineoptions();
  
   //分析表达式
   parser p = parser.createparser(context,option);
   ironpython.compiler.ast.expression ex = p.parseexpression();
  
   //递归查找
   mywalker w = new mywalker();
   ex.walk(w);
   }
   }
   class mywalker : pythonwalker {
   public override bool walk(memberexpression node) {
   console.writeline("walk:{0},{1}", node.name, node.target);
   return base.walk(node);
   }
   }