[集成IronPython] 使CLR对象对动态语言更友好(二)—— 支持切片

在上一节中, 我们在一个CLR对象上实现了几个SpecialName方法。实在是一个非常Special的Attribute。不管怎样,你会发现,在IronPython的扩展方面,这个东东将无处不在。


今天,我们将实现一个Collection对象,并且让这个Collection对象支持IronPython的一个最重要的功能——Slice(切片)。

还是先来看效果:


 附件: 您所在的用户组无法下载或查看附件


注:大家一定很奇怪,我为什么总是在使用IDE的Output窗口来查看print效果。还记得总目录里面有一章一直没有写吗?呵呵,因为我一直不知道如何重定向IronPython的标准输入输出。因此,只好拿Output窗口充数了。

另外一个需要说明的,大家会发现上面的输出窗口中多了几个空行,这个可能是因为"\r\n"和"\n"的差别引起的。


下面是IronPython的代码:

print TestCollection[0:9:2]

简单来说,“切片”是IronPython在序列类型对象(字符串,列表和元组)上支持的一套特殊的运算符。语法是:sequence[starting_index:ending_index:step]。意思是说,取出序列中从starting_index开始到ending_index结束,每隔step个元素组成的新序列。很实用的一个功能哦。


具体的IronPython的语法不是我们讨论的重点,我们直接切入主题,看看我怎样让我的一个Collection对象支持切片操作。


为了展示,我从System.Collections.ObjectModel.Collection<T>继承了一个Collection对象(这仅仅是为了实现的方便,你完全可以从头开始实现ICollection接口去实现一个你自己的Collection对象)。当我将这个对象添加到我的测试程序中后(新的DLRFriendlyCollection同上一节的DLRFriendlyObject一样,和DLConsole的实现没有直接的关系,因此它们都被定义在了测试工程中)。发现,如果调用切片操作,会产生一个ArgumentTypeException。(我还以为微软会将这个功能直接做在兼容性考虑里面呢)看来还是要们自己来做。

好在IronPython中提供了Slice对象。也就是说,你只需要在你的对象上实现了特定的接口,就可以提供对切片的支持了。让我们先从最基本的入手——取一个切片。

Code


呵呵,很简单,你只需要实现一个接受IronPython.Runtime.Slice对象作为参数的的索引器就可以了。并且让这个索引器返回一个枚举类型对象。

当然,IronPython关于切片的操作并不仅仅是取出一个切片,它还可以通过切片修改序列。下面是Set函数的实现:

set方法的实现

Code


Python对切片的操作逻辑很复杂,这里就不详细的讨论了。我在上面的代码中加入了一些注释。相信可以帮助你理解实现。


最后,还有删除的操作:

删除方法的实现

Code


注意,IronPython使用反射调用这些方法,因此不会有任何编译时检查,你需要自己确保这些方法的签名正确。(这一点,是我们这些静态类型语言er最不能理解的。)

最后再给一个IronPython中看起来酷酷的功能——列表解析


 附件: 您所在的用户组无法下载或查看附件

IronPython代码如下:

print [ i for i in TestCollection if int(i) % 2 == 0 ]
也就是说,返回一个符合if后面条件的项目的集合。呵呵,是不是有点像Linq的语法,幸运的是,支持上面的语法,我们不需要写任何代码。否则,我又要写一篇Blog了。

好的,我们已经实现了一些我认为对于IronPython很重要的一些语法的支持。IronPython还有很多重要的语法,可以帮助开发人员快速的实现业务逻辑,而不像C#那样,什么都还没有做,先自动生成外加手写了1000+代码。我对IronPython并不很熟悉。如果你对IronPython很熟悉,并且认为IronPython中还有其它的很重要的功能,而你又不知道如何让你的嵌入对象支持这个功能的。在下面留言。我会考虑再写一篇博客实现一下。

这些支持的代码确实已经很精简了(至少比扩展CPython容易多了,《Python核心编程》中关于扩展一节我都没能够深入的读下去,太多的类库和依赖了)。但是,实现这些功能,我们不得不修改现有类型的接口。有时候,这样的修改是难以完成的。比如:

有时候,我们不想在我们的业务逻辑对象上暴露这些类似"__delslice__"的方法。
有时候,我们不能在已有的系统已经定义的类型上添加这些方法。
有时候,对象的创建不由我们控制,因此我们也不能通过继承来增加这些方法。

下一节,我们将会不通过继承,在已有CLR类型上添加这些方法。每周一节,敬请关注

大家可以从这里下载可运行的源代码。





(文/Cajon  出处/博客园)

 感谢原创者的辛勤劳动,希望对您有所帮助,转载请注明原出处。
 您可能对 [Visual Studio.NET] 的这些文章也感兴趣:

Copy Screen Object to Bitmap File
.NET脏字过滤算法的改进
微软决定取消MEDC大会
Sending email with an embedded image through ASP.NET
基于.Net平台应用程序唯一运行实例C#代码实现
.NET框架图解之四:System.Data
StyleCop SDK发布:解决规则不可定制化
Net60将让.NET CF支持Symbian OS
Typemock发布Isolator 5.1.1和Racer
使LumaQQ.NET支持接收长消息