Hello World
Spiga

标签:表达式树

当类型转换表达式遇上自定义转换操作

2010-10-15 05:50 by 老赵, 1013 visits
摘要:之前我提到说System.Json是一个十分不好用的类库,其中一点就是在于,我没法将一个JsonValue转化为范型类型——它只为Int32,String等几种特定类型定义了隐式转换,又无法得到以object类型所引用的值。不过这也难不到拥有“在运行时创建自定义表达式树并编译成动态代码”的.NET程序员。我们可以写一个辅助方法进行JsonValue至任意类型的转化操作,.NET类库会负责为我们选择合适的转换方式。只不过,类库中的一个Bug会让我们稍微绕一点点弯路。 阅读全文

使用.NET 4.0中的表达式树生成动态方法

2010-05-12 17:03 by 老赵, 2608 visits
摘要:为了在模型为dynamic类型的视图中使用一个匿名对象,我们在上一篇文章里为匿名对象创建了对应的动态类型。于是在使用时,我们会创建动态类型的对象,然后将匿名对象的属性赋值给动态对象的公开字段上。在赋值时我们使用了反射,再加上这个方法使用比较频繁,因此使用更好的方法来优化性能便是个很自然的选择。在.NET 1.0中,我们需要Emit;在.NET 2.0中则增加了DynamicMethod,相对简化了单个动态方法的创建过程;在.NET 3.5中则增加了可编译表达式树,可谓前进了一大步——那么在.NET 4.0中呢? 阅读全文

“表达式树”配合“泛型参数字典”定义通用操作

2009-11-13 05:53 by 老赵, 16059 visits
摘要:上午有朋友提出了这么一个问题:如何定义一个通用的相加操作。其实这可以利用“泛型参数字典”和“表达式树”配合完成,也有着非常优秀的性能。于是,我们便可以定义一个比.NET框架自带的Enumerable.Sum强大许多的扩展方法了。 阅读全文

统计一个表达式树拥有的节点数量

2009-10-31 13:05 by 老赵, 14753 visits
摘要:如果要统计表达式树的节点数量,我们可以编写一个Expression Visitor来完成这个任务。值得注意的是,由于ExpressionVisitor只负责“遍历”,因此在进行“统计”、“收集信息”等任务的时候,都需要在子类内部保存临时信息。因此,许多ExpressionVisitor的实现其实都不是线程安全的。一般说来,由于自动生成闭包等机制,一个Lambda表达式实际构造出的节点总比我们“看出”的要多一些。 阅读全文

趣味编程:C#中Specification模式的实现(参考答案 - 下)

2009-09-29 02:35 by 老赵, 10856 visits
摘要:上一篇文章中我们利用C#语言的特性实现了一种轻量级的Specification模式,它的关键在于抛弃了具体的Specification类型,而是使用一个委托对象代替唯一关键的IsSatisfiedBy方法逻辑。据我们分析,其优势之一在于使用简单,其劣势之一在于无法静态表示。但是它们还都是在处理“业务逻辑”,如果涉及到一个用于LINQ查询或其他地方的表达式树,则问题就不那么简单了——但也没有我们想象的那么复杂。 阅读全文

基于DelegateEvent创建第一个IEvent对象

2009-09-11 05:47 by 老赵, 11028 visits
摘要:继续和“事件即对象”打交道。我们之前提到过两个“趣味编程”:DelegateEvent与Functional Reactive Programming,现在我们在它们两者之间架起一座桥梁。也就是说,我们要从一个DelegateEvent对象创建一个IEvent对象出来。这样,您就可以把它作为第一个IEvent对象,继续尝试Functional Reactive Programming了。 阅读全文

把事件当作对象进行传递

2009-09-07 09:20 by 老赵, 5882 visits
摘要:最近在琢磨一些事情,和API设计有关。API设计在很多时候是和语言特性有关的,因此如Java这样的语言,在API设计时会处处受到压抑。而C#就能够出现如Moq或Fluent NHIbernate这样的项目。同样,F#能够开发出FsTest,Scala号称Scalable Language,都是依靠着丰富的语言特性。不过,最近在使用C#的时候鼻子上也碰了一点灰,这是因为我发现“事件”这个东西没法作为对象进行传递。 阅读全文

通过表达式树构造URL时忽略部分参数

2009-09-03 03:37 by 老赵, 3892 visits
摘要:您的使用ASP.NET MVC的时候,一定遇到过使用Post接受数据的Action方法。为了实现这个功能,我们必须在客户端准备一个form,并填写它的Action——也就是Post的目标URL。按照传统的做法,我们会使用表达式树来构造这个URL,但因为ASP.NET Routing在处理配置规则中没有标明的Route Values时,会将它们作为Query String拼接在URL后面。因此,我们需要得到一种“忽略”某个参数的方式。 阅读全文

优化通过表达式树构造URL的性能

2009-09-01 11:29 by 老赵, 4102 visits
摘要:我们继续改进通过表达式树构造URL的方式。在上一篇文章中,辅助方法可以正确地识别了ActionNameAttribute,而这次改进的则是性能方面的问题。原先的代码使用了传统计算一个表达式树的方式:“使用LambdaExpression对象封装,再编译,最后执行”来获得一个Expression对象的值。但是,Compile方法的性能是比较低下的,如果密集地执行会对性能产生一定影响。我们可以使用FastLambda中的组件来优化这部分操作的性能。 阅读全文

通过表达式树构建URL时正确识别ActionNameAttribute

2009-09-01 06:25 by 老赵, 3741 visits
摘要:在MvcFutures项目中提供了一个辅助方法,可以将一个表达式树对象转化成一个RouteValueDictionary集合。只可惜,这个辅助方法的毛病比较多。例如,它直接把方法名作为action的值,而忽略了其上标记的ActionNameAttribute。这导致了某个被“改名”的Action方法一旦用在了表达式树中,最终得到的URL便是错误的。不过只需寥寥数行代码便可改变这个情况。 阅读全文

使用表达式树构建DomainRoute的URL

2009-08-31 07:48 by 老赵, 3820 visits
摘要:由于DomainRoute支持针对URL域名的捕获和构造,这有些破坏了ASP.NET Routing所制定的“协议”(ASP.NET Routing只支持Path),因此在上一篇文章中,我们需要自己构造一个辅助方法来获得一个“包含域名”的URL。不过根据尽可能强类型的原则,我们应该使用的是类似于MvcFutures中定义的基于表达式树的辅助方法。由于MvcFutures已经提供了非常充足的辅助功能,因此这其实并不需要耗费我们多少代价。 阅读全文

快速计算表达式树

2009-07-29 01:25 by 老赵, 6648 visits
摘要:.NET 3.5中新增的表达式树(Expression Tree)特性,第一次在.NET平台中引入了“逻辑即数据”的概念,它是LINQ to Everything在技术实现上的重要基石之一。对表达式树进行计算,是处理表达式树时中最常见的工作了。根据我的本地测试结果,在一台P4 2.0 GHz的服务器上,单线程连续计算一万个简单的四则运算表达式便要花费超过1秒钟时间。这并非是一个可以忽略的性能开销,引入一种性能更好的表达式树计算方法势在必行。 阅读全文

谈表达式树的缓存(7):五种缓存方式的总体分析及改进方案

2009-05-31 14:47 by 老赵, 20930 visits
摘要:终于到了这个系列的最后一篇文章了,这个系列的文章本是许多话题的基础,却拖了那么长时间还没有完结。这篇文章主要讨论五种缓存方式各自的优劣,以及他们的性能关键在什么地方,如果要进行改进又有什么可选方案。在这个问题上,老赵的思考可能会有遗漏,如果您有任何补充,也请不吝指出。 阅读全文

谈表达式树的缓存(6):五种缓存方式的性能比较

2009-05-26 13:06 by 老赵, 21980 visits
摘要:目前我们已经涉及了五种不同的缓存实现(SimpleKeyCache、PrefixTreeCache、SortedListCache、HashedListCache和DictionaryCache),如果要从一个已经包含n个表达式树的存储中,查找一个有m个节点的表达式树,根据几篇文章的分析,从理论上说除了HashedListCache的时间复杂度是O(m * log(n))之外,其它几种实现的时间复杂度都是O(m)。不过,理论上的结果和实际使用中的效果完全符合吗?那么我们就写一个程序,让数据说话。这是一个控制台应用程序,接受用户参数,并由此生成试验数据,或进行性能比较。 阅读全文

谈表达式树的缓存(5):引入散列值

2009-03-19 17:40 by 老赵, 11995 visits
摘要:到目前为止,我们已经实现了三种缓存方式:首先我们设法构建唯一字符串,但是由于它的代价较高,于是我们使用了前缀树进行存储;又由于前缀树在实际操作中所花的时间和空间都有不令人满意之处,我们又引入了二叉搜索树。那么二叉搜索树又有什么缺点呢? 阅读全文

谈表达式树的缓存(4):使用二叉搜索树(AVL树)

2009-03-19 01:05 by 老赵, 8524 visits
摘要:上一篇文章中谈到的前缀树实现方式,时间复杂度从理论上来讲已经达到了最优,而空间复杂度理论上也可以做到较优。但是理论和实际是有差别的,而对于上文前缀树的实现来说,这两方面并不是非常理想。因此,虽然事实上前缀树是老赵第一个真正实现的缓存方法,但是对此并不满意,也想着有什么办法可以进行优化。不如尝试一下使用二叉搜索树? 阅读全文

谈表达式树的缓存(3):使用前缀树

2009-03-17 17:24 by 老赵, 8032 visits
摘要:在上一篇文章里我们设法将前缀树构造为一个唯一的字符串,然后使用字符串作为key缓存在字典中。这个想法非常直接,做法也不困难(在遍历时记录详细信息便可)。不过事实上,老赵在思考表达式树的缓存问题时,这种字符串拼接的方式只存在于脑海当中,而上文的实现是为了这一系列文章的完整性而特地编写的。这是因为它的缺点较为明显,正如上文所述,字符串拼接操作较为耗时耗资源,且很容易生成一个长度可观的字符串(并非不能优化,不过实现就复杂了)。于是我们现在设法选择另一个解决方案来处理这个问题。 阅读全文

谈表达式树的缓存(2):由表达式树生成字符串

2009-03-16 16:58 by 老赵, 8386 visits
摘要:谈到使用表达式树作为key进行缓存,您脑海中最早浮现出来的解决方案是什么?老赵看来,大部分朋友的第一反应自然就是将作为key的表达式树,使用一定规则生成一个字符串。那么我们就先使用这个办法来解决问题。 阅读全文

谈表达式树的缓存(1):引言

2009-03-16 01:29 by 老赵, 10381 visits
摘要:表达式树(Expression Tree)是.NET 3.5中引入的一种表达方式。表达式树的运用十分广泛,可以直观地表现出各种“数据”,甚至“逻辑”和“行为”。老赵现在希望可以找到一种较为通用的,能够根据表达式树进行缓存的解决方案。在这一系列文章中,老赵希望可以重现自己在思考这个问题的时候所形成的完整思考路径。相比最终解决方案,这可能才是更有价值的东西。至少我觉得讨论一下这个问题也是非常有意思的事情。而且从一定程度上说,这些思考能够在一定程度上体现出算法设计与数据结构的美妙之处。 阅读全文
1
使用Live Messenger联系我