在我們的.net項(xiàng)目中,要使用到自定義公式功能,我們利用了ironpython的lambda功能,可以方便的計(jì)算值,但是我們發(fā)現(xiàn),如果表達(dá)式涉及的屬性發(fā)生改變時(shí),公式必須重新計(jì)算,怎樣析表達(dá)式知道到底訪問了哪些屬性呢?
在我們的.net項(xiàng)目中,要使用到自定義公式功能,我們利用了ironpython的lambda功能,可以方便的計(jì)算值,但是我們發(fā)現(xiàn),如果表達(dá)式涉及的屬性發(fā)生改變時(shí),公式必須重新計(jì)算,怎樣析表達(dá)式知道到底訪問了哪些屬性呢?
仔細(xì)研究發(fā)現(xiàn)ironpython提供了這樣的功能:
以下為引用的內(nèi)容: 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(); |
上面的代碼分析了表達(dá)式:activeobject.contact.address + 'ds', 這里用了parser類可以分析出表達(dá)式,使用vs對象查看器,可以理解結(jié)果:
問題還沒有完全解決,我想結(jié)果有了,我總不能自己遞歸所有結(jié)構(gòu)吧?哇,怎么也有20多種類型,在看看,嗯,還有這個(gè):
以下為引用的內(nèi)容: 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!!我重載的虛方法被調(diào)用了兩次,告訴我有2次字段的訪問。
在.net 3.5中提供了lambda的結(jié)構(gòu)描述類,但我是沒有找到動(dòng)態(tài)編譯分析的類。看博客園的朋友說:本來有個(gè)dynamicexpression的類提供了動(dòng)態(tài)編譯功能,但是現(xiàn)在的.net 3.5砍掉了,但是在linq 101 samples中卻有源代碼,靠。
注意:本程序使用ironpython 的1.0版本,2.0版本的方法已經(jīng)不同。 下面是2.0的代碼:
以下為引用的內(nèi)容: class program {static void main(string[] args) { //引擎 ironpython.hosting.pythonengine engine = ironpython.hosting.pythonengine.currentengine; //代碼單元 sourcecodeunit unit = new sourcecodeunit(engine, "activeobject.contact.address + 'ds'"); //上下文和選項(xiàng) compilercontext context = new compilercontext(unit); ironpython.pythonengineoptions option = new ironpython.pythonengineoptions(); //分析表達(dá)式 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); } } |
新聞熱點(diǎn)
疑難解答
圖片精選